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:
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.
Der Code im C++ Builder:
Header:
Code:
//---------------------------------------------------------------------------
#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
Implementierung:
Code:
//---------------------------------------------------------------------------
#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();
}
}
//---------------------------------------------------------------------------
Schon das Laden der
DLL mit LoadLibrary hat nicht geklappt, erst LoadLibraryEx brachte den nötigen Erfolg.
GetProcAddress findet die Funktion nicht und GetLastError liefert 126 zurück.
Bitte um Hilfe und Danke im voraus.