dll in C++ erstellen und in delphi nutzen.



  • Moin.

    Was ich machen möchte, steht ja schon im Titel.

    Ich habe unter VS2008 Pro ein Win32 dll Projekt erstellt und habe es unverändert kompiliert.

    // Folgender ifdef-Block ist die Standardmethode zum Erstellen von Makros, die das Exportieren 
    // aus einer DLL vereinfachen. Alle Dateien in dieser DLL werden mit dem WINDRIVER02_EXPORTS-Symbol
    // kompiliert, das in der Befehlszeile definiert wurde. Das Symbol darf nicht für ein Projekt definiert werden,
    // das diese DLL verwendet. Alle anderen Projekte, deren Quelldateien diese Datei beinhalten, erkennen 
    // WINDRIVER02_API-Funktionen als aus einer DLL importiert, während die DLL
    // mit diesem Makro definierte Symbole als exportiert ansieht.
    #ifdef WINDRIVER02_EXPORTS
    #define WINDRIVER02_API __declspec(dllexport)
    #else
    #define WINDRIVER02_API __declspec(dllimport)
    #endif
    
    // Diese Klasse wird aus WinDriver02.dll exportiert.
    class WINDRIVER02_API CWinDriver02 {
    public:
    	CWinDriver02(void);
    	// TODO: Hier die Methoden hinzufügen.
    };
    
    extern WINDRIVER02_API int nWinDriver02;
    
    WINDRIVER02_API int fnWinDriver02(void);
    
    // WinDriver02.cpp : Definiert die exportierten Funktionen für die DLL-Anwendung.
    //
    
    #include "stdafx.h"
    #include "WinDriver02.h"
    
    // Dies ist das Beispiel einer exportierten Variable.
    WINDRIVER02_API int nWinDriver02=0;
    
    // Dies ist das Beispiel einer exportierten Funktion.
    WINDRIVER02_API int fnWinDriver02(void)
    {
    	return 42;
    }
    
    // Dies ist der Konstruktor einer Klasse, die exportiert wurde.
    // Siehe WinDriver02.h für die Klassendefinition.
    CWinDriver02::CWinDriver02()
    {
    	return;
    }
    

    Nun habe ich versucht die Funktion fnWinDriver02 mit einer in Delphi geschriebenen Anwendung zu benutzen:

    implementation
    
      function fnWinDriver02(): Integer; stdcall;
        external 'WinDriver02.dll';
    
    {$R *.dfm}
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Button1.Caption := IntToStr(fnWinDriver02());
    end;
    

    Nur leider kommt da die Meldung:

    ---------------------------
    CppDllTest.exe - Einsprungpunkt nicht gefunden
    ---------------------------
    Der Prozedureinsprungpunkt "fnWinDriver02" wurde in der DLL "WinDriver02.dll" nicht gefunden.
    ---------------------------
    OK
    ---------------------------

    Was mache ich falsch?



  • Ich würde es mal mit

    WINDRIVER02_API extern "C" int fnWinDriver02(void);
    

    versuchen.



  • Viele Dank für die Antwort.

    Leider kommt die Meldung immer noch.

    Beim kompilieren werden dann diese Warnungen ausgegeben:

    1>WinDriver02.cpp
    1>d:\eigene dateien\visual studio 2008\projects\windriver02\windriver02.h(23) : warning C4518: '__declspec(dllexport)': Unerwartete(r) Speicherklassen- oder Typspezifizierer; wird ignoriert
    1>d:\eigene dateien\visual studio 2008\projects\windriver02\windriver02.h(23) : warning C4502: 'Bindungsangabe' erfordert die Verwendung des Schlüsselwortes 'extern' und muss vor allen anderen Spezifizierern stehen
    1>d:\eigene dateien\visual studio 2008\projects\windriver02\windriver02.cpp(13) : warning C4518: '__declspec(dllexport)': Unerwartete(r) Speicherklassen- oder Typspezifizierer; wird ignoriert
    1>d:\eigene dateien\visual studio 2008\projects\windriver02\windriver02.cpp(13) : warning C4502: 'Bindungsangabe' erfordert die Verwendung des Schlüsselwortes 'extern' und muss vor allen anderen Spezifizierern stehen
    1>Verknüpfen...



  • Bei mir sieht das so aus:

    #ifdef __cplusplus
    extern "C"
    {
    #endif
    //In diesen Block alle Deklarationen mit C - Bindung packen
    WINDRIVER02_API int fnWinDriver02(void);
    
    #ifdef __cplusplus
    }
    #endif
    


  • Eventuell hilft dir folgendes:
    http://en.wikipedia.org/wiki/Dynamic-link_library

    #include "stdafx.h"
    

    <- vielleicht bin ich zu extrem, wenn verschiedene Compilerhersteller an einem Projekt beteiligt sind würde ich möglichst compilerspezifischen Code meiden.

    Die DLL-Schnittstelle wurde ursprünglich für C entwickelt. War da nicht etwas mit den Aufrufkonventionen? Zu 16-bit Zeiten musste man da Unterschiede zwischen C und Pascal berücksichtigen und dies per Code richtig definieren 😕 Ob das heute noch so ist?

    MfG f.-th.



  • Nachtrag hab den Link überflogen:

    implementation
    
      function fnWinDriver02(): Integer; stdcall;
      cdecl;   // muss immer noch um Pascal-Konventionen für C verfügbar zu machen.
        external 'WinDriver02.dll';
      ...
    


  • Funktioniert 🙂

    Vielen Dank.


Anmelden zum Antworten