![]() |
Delphi-DLL in C++ benutzen
Hallo Forum,
ich muss eine DLL an einen Kunden geben der mit LabWindows/CVI von NI (AnsiC) arbeitet. Da ich Delphi-Programmierer bin erstelle ich die DLL in Delphi. Zum Testen nutze ich den C++Builder da ich nunmal RAD Studio XE besitze. Mein Laptop läuft mit Win7Pro(x64). 1. Ich habe die DLL mit einer Delphi-Applikation getestet (Dll-Funktionen statisch eingebunden) -> funktioniert. 2. Versuche die DLL statisch in C++ einzubinden hab ich überhaupt nicht hingekriegt. 3. Versuche die DLL zur Laufzeit in C++ einzubinden funktionieren bis zum laden der DLL. Funktionen aus der DLL gehen gar nicht. 4. Damit ich weiterkomme habe ich nochmal eine neue Minimal-DLL mit nur zwei Funktionen erstellt. Parallel dazu habe ich eine Minimalanwendung im C++Builder erstellt. Beides hänge ich hier an. Mich interessiert im ersten Punkt: - Wie krieg ich meinen Code zum Laufen? Fernerhin eine Art Tutorial wie Delphi-DLL's erstellt werden müssen damit sie in C eingebunden werden können. - Wie muss die DLL aussehen? - Wie kann ich die LIB- und Header-Datei erzeugen (spezielle Projektoptionen in Delphi??) zur Weitergabe an den Kunden? - Wie läßt sich die DLL dann in C++-Builder einbinden (statisch und zur Laufzeit)? In Delphi war das alles ganz verständlich, aber hier... Ich vermute das hier auch der Aspekt Win7(x64) einen Einfluss hat. Der Code: Die DLL (in Delphi XE):
Delphi-Quellcode:
Der Code im C++ Builder:
library Project1;
uses SysUtils, Classes; {$R *.res} function Min(X, Y: Integer): Integer; stdcall; begin if X < Y then Min := X else Min := Y; end; function Max(X, Y: Integer): Integer; stdcall; begin if X > Y then Max := X else Max := Y; end; exports Min, Max; begin end. Header:
Code:
Implementierung:
//---------------------------------------------------------------------------
#ifndef Unit1H #define Unit1H //--------------------------------------------------------------------------- #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> #include <FileCtrl.hpp> //--------------------------------------------------------------------------- class TForm1 : public TForm { __published: // Von der IDE verwaltete Komponenten TButton *Button1; TLabel *Label1; TButton *Button2; TButton *Button3; TEdit *Edit1; TEdit *Edit2; void __fastcall Button1Click(TObject *Sender); void __fastcall Button3Click(TObject *Sender); void __fastcall Button2Click(TObject *Sender); private: // Anwender-Deklarationen HINSTANCE DllInstance; public: // Anwender-Deklarationen __fastcall TForm1(TComponent* Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TForm1 *Form1; //--------------------------------------------------------------------------- #endif
Code:
Schon das Laden der DLL mit LoadLibrary hat nicht geklappt, erst LoadLibraryEx brachte den nötigen Erfolg.
//---------------------------------------------------------------------------
#include <vcl.h> #pragma hdrstop #include "windows.h" #include "winbase.h" #include "Unit1.h" #define LOAD_LIBRARY_AS_DATAFILE 0x00000002 //TCHAR dllToLoad[] = L"CEH_IPC.dll"; // The dll's complete name //TCHAR dllToLoad[] = L"zlib.dll"; // The dll's complete name TCHAR dllToLoad[] = L"Project1.dll"; // The dll's complete name //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { // DllInstance = LoadLibrary((wchar_t *)"D:\CPP\Sandkasten\Test\CEH_IPC.dll"); DWORD TestRes = 12; if (!DllInstance) DllInstance = LoadLibraryEx(dllToLoad,NULL,LOAD_LIBRARY_AS_DATAFILE); if (DllInstance) Form1->Caption = "DLL wurde geladen."; TestRes = GetLastError(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { if (DllInstance) if (FreeLibrary(DllInstance)) DllInstance = NULL; if (!DllInstance) Form1->Caption = "DLL nicht geladen."; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { typedef int (__stdcall *IMPFUNC) (int, int); IMPFUNC DLLFunktion = NULL; DWORD TestRes = 12; if (DllInstance) { // DLLFunktion = (IMPFUNC)GetProcAddress(DllInstance, "_gzclose@16"); DLLFunktion = (IMPFUNC)GetProcAddress(DllInstance, "Min"); if (DLLFunktion) { TestRes = DLLFunktion(300,400); ShowMessage("Geht doch"); } else { ShowMessage("Geht net"); } TestRes = GetLastError(); } } //--------------------------------------------------------------------------- GetProcAddress findet die Funktion nicht und GetLastError liefert 126 zurück. Bitte um Hilfe und Danke im voraus. |
AW: Delphi-DLL in C++ benutzen
Code:
Du lädst die DLL ja auch als Datendatei. Ich bin mir nicht sicher, ob man dann Funktionen aus der DLL nutzen kann. Das MSDN geht im Moment leider nicht.
DllInstance = LoadLibraryEx(dllToLoad,NULL,LOAD_LIBRARY_AS_DATAFILE);
Und sind deine C++ Anwendungen auch 32-Bit Anwendungen? |
AW: Delphi-DLL in C++ benutzen
Hallo MaxDelphi,
auf die Schnelle: ich würde als Aufrufkonvention cdecl anstelle von stdcall verwenden (in der Delphi-DLL). Gruß blauweiss |
AW: Delphi-DLL in C++ benutzen
Erstmal Danke für die schnelle Antwort.
@Lucki: Der Hinweis ist korrekt, als Datendatei lassen sich keine Proceduradressen ermitteln. Aber was sollte man dafür benutzten (ich hab testweise LOAD_IGNORE_CODE_AUTHZ_LEVEL verwendet, damit ging es). (((Wenn ich LoadLibrary benutzen könnte hätte ich das Problem gar nicht!))) Ich werd verrückt jetzt geht auch LoadLibrary! Ich hab gestern den ganzen Tag gesucht und ursprünglich mit
Code:
gearbeitet, nach einiger Recherche im Internet dann mit
DllInstance = LoadLibrary((wchar_t *)"D:\CPP\Sandkasten\Test\CEH_IPC.dll");
Code:
gearbeitet und nicht mehr getestet ob auch
DllInstance = LoadLibraryEx(dllToLoad,NULL,LOAD_LIBRARY_AS_DATAFILE);
Code:
geht. Der ursprüngliche Fehler lag also in der Typumwandlung.
DllInstance = LoadLibrary(dllToLoad);
Also das erste Problem scheint gelöst zu sein. @blauweis: Deinen Hinweis werd ich nicht weiterverfolgen (siehe oben). Bleibt die Fragestellung: - Wenn ich eine DLL weitergeben will und der andere eine LIB- und eine Header-Datei braucht. Wie kann ich die erzeugen und auf die Schnelle mal in C++Builder testen? |
AW: Delphi-DLL in C++ benutzen
Zitat:
|
AW: Delphi-DLL in C++ benutzen
@Robotiker:
Ich war scheinbar nicht exakt genug! Ich meinte: Eine DLL mit Delphi erstellen und (am besten nebenbei über Projektoptionen??? oder änlilches) beim Kompilieren/Linken die LIB- und Header-Datei erzeugen. Oder wenn das nicht geht ein Tool das diese Aufgabe übernimmt und eine entsprechende Beschreibung. Für die Header-Datei könnte ich mir ein Übersetzungs-Tool vorstellen ähnlich headconv von Dr. Bob nur von Pascal nach C. Ich habe bereits implib und impdef ausprobiert. implib bricht mit einer Fehlermeldung ab, erzeugt aber eine Lib-Datei. Hier fehlt mir wieder die Möglichkeit zu testen ob sie funktioniert. Kann sein das implib die Lib-Datei korrekt erzeugt hat und erst danach abbricht aber genau weiß ich das nicht. Fehlermeldung von implib: Implib funktioniert nicht mehr Windows kann online nach .... Details: Problemsignatur: Problemereignisname: APPCRASH Anwendungsname: implib.exe Anwendungsversion: 3.2.0.0 Anwendungszeitstempel: 00000000 Fehlermodulname: implib.exe Fehlermodulversion: 3.2.0.0 Fehlermodulzeitstempel: 00000000 Ausnahmecode: c0000005 Ausnahmeoffset: 00013887 Betriebsystemversion: 6.1.7601.2.1.0.256.48 Gebietsschema-ID: 1031 Zusatzinformation 1: d893 Zusatzinformation 2: d8933a9100d220db76612cd68cf270ed Zusatzinformation 3: 712b Zusatzinformation 4: 712bad326e73717ee07100af4c008660 Lesen Sie unsere Datenschutzbestimmungen online: ![]() Wenn die Onlinedatenschutzbestimmungen nicht verfügbar sind, lesen Sie unsere Datenschutzbestimmungen offline: C:\windows\system32\de-DE\erofflps.txt Bitte beachtet ich benutze Win7Pro(x64). |
AW: Delphi-DLL in C++ benutzen
Zitat:
Zitat:
Das einzige Tool, das ich kenne, das Headerdateien aus *.pas Dateien erzeugt, ist der C++ Builder. Wenn man einem C++ Projekt eine Delphi Unit hinzufügt, baut er sich beim Übersetzen eine *.hpp Datei dafür. Die ist aber dafür gedacht die Unit aus einer Builder Anwendung zu nutzen, nicht um Dll-Exporte zu erzeugen. Schreibt Dir doch selber ein Tool, das aus den Signaturen der Delphi-Funktionen die entsprechenden C-Header Einträge generiert und Code mit GetProcAddress-Aufrufen erzeugt. Dann kannst du auf die Lib-Dateien verzichten. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:48 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz