Einzelnen Beitrag anzeigen

MaxDelphi

Registriert seit: 29. Jun 2009
17 Beiträge
 
#1

Delphi-DLL in C++ benutzen

  Alt 7. Jul 2011, 09:59
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.
MfG,
MaxDelphi
  Mit Zitat antworten Zitat