lib erstellen (c++) für c programm



  • das ist der code für die lib

    #include <windows.h>
    #include <shlobj.h>
    #include <tlhelp32.h>
    #include <crtdbg.h>
    
    __declspec(dllexport) void __cdecl WinFWBypass(char *appName);
    
    HRESULT func2()
    {
    
    }
    
    __declspec(dllexport) void __cdecl func1(char *appName)
    {
    
    }
    

    dann in meinem c programm einfach den prototyp bekannt gemacht

    int func1(char *appName);
    

    und die erstellete lib im linker angegeben



  • Kann es sein, dass ein extern "C" fehlt?



  • ops hab vergessen den einen funktions name zu editieren, nur das keine falschen vermutungen aufkommen es soll keine maleware werden sondern nur ein chat programm was ich für die windows firewall freischalten möchte 😉



  • extern "C"
    {
    __declspec(dllexport) void __cdecl func1(char *appName)
    {
    
    }
    }
    

    einfach dann so ?



  • Ich glaube, es reicht auch, wenn du einen extern "C" Block im Header um die Prototypen packst. Aber probier doch einfach mal. Klappt's?



  • also ohne den extern c block geht es nicht

    extern "C"
    {
    void func1(char *appName);
    }
    

    sp bekomme ich syntaxfehler, danke schonmal für die tipps 🙂



  • steff' schrieb:

    sp bekomme ich syntaxfehler

    Es reicht generell nicht, hier einfach zu schreiben, dass du Fehler bekommst. Du musst schon sagen, welche Fehler (genaue Fehlermeldung per Copy&Paste).

    Außerdem bin ich nicht sicher, ob du den Däckelspeck beim Prototypen einfach weglassen darfst. Notiere den Prototypen mal genau wie bei der Implementation.

    Hier gibt's passende Doku: http://msdn.microsoft.com/en-us/library/z4zxe9k8(v=vs.80).aspx


  • Mod

    Mal ein vollständiges Beispiel mit Erklärung:
    Angenommen, du hast die C++-Funktion

    void cpp_funktion(bool foo, const std::string& bar)
    {
      if (foo)
        std::cout << bar << '\n';
    }
    

    Da das aus C sowieso nicht aufrufbar ist, brauchst du erst einmal eine Kompatibilitätsschicht, die dir überhaupt den Aufruf ermöglicht:

    void c_kompatible_funktion(int foo, const char* bar)
    {
      cpp_funktion(foo, bar);
    }
    

    Falls deine ursprüngliche Funktion schon C-kompatibel ist, kannst du dir diesen Schritt sparen und gleich mit deiner Originalfunktion so verfahren wie ich im Folgenden mit der Wrapperfunktion verfahre.

    C++ hat Funktionsüberladung und andere Sachen die C nicht kennt. Intern wird dies dadurch gelöst, dass die Funktionen hinterher gar nicht mehr ihren eigentlichen Namen haben, sondern auch noch der Typ der Parameter in die Symbolnamen in einer Bibliothek aufgenommen wird ("name mangling"). Ein C-Linker kann die Funktionen daher nicht unter dem Namen finden, den er erwartet. Daher muss die Schnittstellenfunktion so übersetzt werden, dass der Name des Symbols im Output nicht verändert wird. Dazu ist das extern "C" da. Wir schreiben uns einen passenden Header:

    #ifndef HEADER_H
    #define HEADER_H
    
    extern "C" {
      void c_kompatible_funktion(int foo, const char* bar);
    }
    
    #endif
    

    Da wir faul sind, wollen wir den gleichen Header für C und C++ benutzen, daher ein bisschen Präprozessormagie:

    #ifndef HEADER_H
    #define HEADER_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
      void c_kompatible_funktion(int foo, const char* bar);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    

    Sodann können wir ein C-Programm schreiben:

    #include "header.h"
    
    int main()
    {
      c_kompatible_funktion(123, "Hallo Welt!");
      return 0;
    }
    

    Der C++-Quellcode sieht nun so aus:

    #include <iostream>
    #include <string>
    
    #include "header.h"
    
    void cpp_funktion(bool foo, const std::string& bar)
    {
      if (foo)
        std::cout << bar << '\n';
    }
    
    void c_kompatible_funktion(int foo, const char* bar)
    {
      cpp_funktion(foo, bar);
    }
    

    Wie übersetzen wir dies nun?
    Erst einmal die C++-Bibliothek erstellen (hier Beispiel mit GCC):

    g++ cplusplus.cpp -c -o cplusplus.o
    

    Dies erstellt die Objektdatei cplusplus.o mit dem Symbol c_kompatible_funktion und einem wilden Alternativnamen für die ursprüngliche Funktion cpp_funktion. Wir könnten diese Datei in eine Bibliothek packen, mache ich für das Beispiel aber nicht, da Bibliotheken nichts anderes sind als Sammlungen solcher Objektdateien.
    Dann übersetzen wir den C-Code:

    gcc c.c -c -o c.o
    

    Und linken dann alles zusammen. Nicht vergessen, dass die C++-Standardbiblithek mitgelinkt werden muss, sofern diese vom C++-Code benötigt wird!

    gcc c.o cplusplus.o -lstdc++ -o fertiges_programm
    

    Die letzten beiden Schritte kann man (beim GCC und vielen anderen Compilern) auch direkt zusammenfassen:

    gcc c.c cplusplus.o -lstdc++ -o fertiges_programm
    


  • Erstmal danke sepp für die super ausführliche antwort. leider haut es bei mir noch immer nicht hin, weiterhin linker fehler. ich mache das ganez aber auch mit VS und nicht mit gcc , vlt liegt es ja daran ? hab in VS die lib dem projekt hinzugefügt und unter linkereinstellungen die lib hinzugefügt. was ich sonst noch machen kann weiss ich nicht..


  • Mod

    steff' schrieb:

    Erstmal danke sepp für die super ausführliche antwort. leider haut es bei mir noch immer nicht hin, weiterhin linker fehler. ich mache das ganez aber auch mit VS und nicht mit gcc , vlt liegt es ja daran ? hab in VS die lib dem projekt hinzugefügt und unter linkereinstellungen die lib hinzugefügt. was ich sonst noch machen kann weiss ich nicht..

    Ich wage mal die Diagnose: Es liegt nicht an deinen Werkzeugen, sondern du machst etwas falsch:

    _matze schrieb:

    Es reicht generell nicht, hier einfach zu schreiben, dass du Fehler bekommst. Du musst schon sagen, welche Fehler (genaue Fehlermeldung per Copy&Paste).



  • Meine c Header sieht so aus

    #ifndef FWBP_H
    #define FWBP_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
      void WinFWBypass(char* appName);
       int AddPortToNat(int listeningPort,char* localIP);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    

    dann der call ganz normal in der c datei.

    meine lib header

    #ifdef __cplusplus
    extern "C" {
    #endif
    
      void WinFWBypass(char* appName);
      int AddPortToNat(int listeningPort,char* localIP);
    
    #ifdef __cplusplus
    }
    #endif
    

    die cpp

    int AddPortToNat(int listeningPort,char *localIP)
    {
    return 1;
    
    void WinFWBypass(char *appName)
    {
    
    return;
    }
    

    Fehlermeldung:

    1> Alle Ausgaben sind aktuell.
    1>main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_WinFWBypass@4" in Funktion "_WinMain@16".
    1>main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_AddPortToNat@8" in Funktion "_WinMain@16".
    1>..\..\fertig\RPC (Reverse Proxy Client)\client.exe : fatal error LNK1120: 2 nicht aufgelöste externe Verweise.

    erstelle den cpp code als lib und habe diesem auch dem c projekt hinzugefügt


Anmelden zum Antworten