Entwickler-Ecke

Dateizugriff - C++ DLL in Delphi verwenden


Johannes Maier - Di 31.08.04 19:59
Titel: C++ DLL in Delphi verwenden
Passt wohl eher in ein Delphi-Forum die Frage ;)
Also ich habe eine DLL, die in C++ geschrieben wurde, sie enthält nur Funktionen. (Falls das einer hier weiß: damit ich sie in Delphi benutzen kann, muss ich sie da mit __stdcall deklarieren? Ansonsten probiere ich aus ;) )
Ich kenne natürlich die Funktionsdeklarationen, mein Frage:
Wie lade ich die DLL (LoadLibrary müsste auch hier gehen oder?) und wichtiger: Wie lade ich die Funktionen. In C++ geht das mit GetProcAddress, gibt es sowas auch in Delphi?
Also in C++ erstelle ich einen Zeiger auf eine Funktionen (Prototyp) und weise diesem dann die mit GetProcAddress(HMODULE (die DLL), 'Name der Funktion') zu. WIe läuft das hier?

MfG
Johannes


Motzi - Di 31.08.04 20:16

LoadLibrary und GetProcAdress sind API-Funktionen, die es natürlich auch unter Delphi gibt. Welche Aufruf-Konventionen die Funktionen verwenden (stdcall, cdecl, ...) ist im Prinzip egal solange du die Imports unter Delphi richtig deklarierst.

Nachdem du schon LoadLibrary und GetProcAdress angesprochen hast nehm ich an du willst die DLL dynamisch importieren. Das geht in Delphi so. Du deklarierst dir mal einen Prozedurzeiger:

Delphi-Quelltext
1:
2:
3:
type
  TMyImportFunc = function (param1: Integer): Boolean; stdcall;
  TMyImportProc = procedure (param1: pointer); cdecl;

Ich hoffe der Unterschied zwischen function und procedure in Delphi ist klar (procedure ist alles was unter C++ VOID als Result liefert). Sonst ist halt nur wichtig, dass du die Parameter richtig übersetzt und die richtige Aufruf-Konvention verwendest. Aufrufen kannst du die Funktion dann so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
var
  hDLL: HModule;
  pFunction: TMyImportFunc;
begin
  hDLL := LoadLibrary('DLL');
  if hDLL <> 0 then
  begin
    @pFunction := GetProcAdress(hDLL, 'FunctionName');
    if Assigned(pFunction) then
      pFunction(<parameter>)
    else
      ShowMessage('Funktion nicht gefunden');
  end;
end;


Johannes Maier - Di 31.08.04 20:25

Ahh cool danke, läuft fast haargenau so wie in C++ auch ;)
Mich hat nur verwundert, dass ich in der Delphi-Hilfe nicht zu LoadLibrary oder GetProcAdress gefunden hab ... aber liegt wohl daran, dass es API-Funktionen sind oder?

danke


Johannes Maier - Di 31.08.04 20:38

Hmm mir fällt grade auf, dass alles auch ohne stdcall bzw. __stdcall klappt. Ich hab in der C++-DLL kein __stdcall verwendet, und es in deinem Quelltext ebenfalls weggelassen. Was genau bringt das dann?


UC-Chewie - Di 31.08.04 20:55

Die Aufrufkonvention bezeiht sich auf die Art der Übergabe von Parametern(und evtl. Rückgabewerten).


Motzi - Di 31.08.04 21:02

Genau.. Dokus zu den APIs findet man im SDK, nicht in der Delphi-Hilfe.. ;)

Die Aufruf-Konvention bezieht sich, wie bereits gesagt, auf die Übergabe von Parametern und eventuellen Rückgabewerten: wie werden die Parameter übergeben - Stack oder Register, wer räumt den Stack wieder auf - die aufrufende Funktion oder die aufgerufene, ...

Wenn die Funktion keine Parameter verwendet fällt es nicht weiter auf wenn man nicht die richtige Aufruf-Konvention verwendet, aber bei umfangreicheren Paramterlisten kann es zu bösen AVs kommen..! Wenn nicht anders deklariert sind deine Funktionen wahrscheinlich cdecl..


Johannes Maier - Di 31.08.04 21:15

Hmm leider stellt sich nun das Problem, dass ich beim Exportieren von zwei Funktionen (beide Integer / int) immer 0 aus der C++-DLL geliefert bekomme (anscheinend);
Es handelt sich um die Funktionen Fakultaet(int) und Potenz(int, int); Ich benutze dieses Mal keine Anweisungen beim Aufruf wie stdcall oder cdecl, da ich vorher Errors bekam, als ich alles mit stdcall gemacht hatte.
Weiß einer, woher mein Problem kommen kann? (bestimmt liegts an den Aufruf-Konventionen ;) )

//Edit: Fehler schon gefunden ;) Wie du sagtest, waren sie cdecl (hab ich ja in C++ selbst vorher eingestellt mit extern "C" { } ich Depp ;) ) ...
Also hat sich mit zwei kleinen cdecl in Delphi das Problem fast von selbst gelöst :)