Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Call einer DLL von einem Delphi Prg (https://www.delphipraxis.net/192361-call-einer-dll-von-einem-delphi-prg.html)

wschrabi 11. Apr 2017 20:50


Call einer DLL von einem Delphi Prg
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Leute,
also ich hab die DLL dyn. gelanden und die SUMME von 1+2+3 klappt auch mit Rückgabewert int.
Doch wenn ich char* zurückgeben will kommt nur nix.

Kann mir da wer sagen, wieso? Ich dachte bei dyn. laden der dll braucht man auf den MemMGR nicht achten?

DANKE für jeden TIPP.

Habe nun das folgende probiert:
Delphi-Quellcode:
procedure TForm2.LadeDLL(Sender: TObject);
begin
  hmod := LoadLibrary('QMC_DLL.dll');
  if (hmod <> 0) then begin
    calcmain := GetProcAddress(hmod, 'calcmain');
    if (@calcmain <> nil) then begin
      ShowMessage('calmain geladen');
    end
    else
      ShowMessage('GetProcAddress failed');
    getttterms := GetProcAddress(hmod, 'getttterms');
    if (@calcmain <> nil) then begin
      ShowMessage('getttterms geladen');
    end
    else
      ShowMessage('GetProcAddress failed');
    calcsum := GetProcAddress(hmod, 'calcsum');
    if (@calcsum <> nil) then begin
      ShowMessage(Format('Calcsum geladen: UND TEST: SUM(1,2,3) = %d',[calcsum(1,2,3)]));
    end
    else
      ShowMessage('GetProcAddress failed');
    dummycdecl := GetProcAddress(hmod, 'dummycdecl');
    if (@dummycdecl <> nil) then begin
      ShowMessage(Format('dummycdecl geladen: UND Return; = %c',[dummycdecl('3')]));
    end
    else
      ShowMessage('GetProcAddress failed');
    dummystdcall := GetProcAddress(hmod, 'dummystdcall');
    if (@dummystdcall <> nil) then begin
      ShowMessage(Format('dummystdcall geladen: UND Return; = %c',[dummystdcall('3')]));
    end
    else
      ShowMessage('GetProcAddress failed');
     
     
  end
  else
    ShowMessage('LoadLibrary Failed!');
end;
die ersten beiden werden geladen bzw die Summe angezeigt. aber die letzten beiden klappen nicht
mehr - da kommt GetProcAddress failed'.

Mein DLL:

Code:
char __declspec(dllexport) __stdcall dummystdcalll(char* inpvec)
{
return inpvec[0]; //resultbuff;

}

char __declspec(dllexport) __cdecl dummycdecl(char* inpvec)
{
return inpvec[0]; //resultbuff;

}
Wer weiß Rat?
DANKE

Fritzew 11. Apr 2017 21:34

AW: Call einer DLL von einem Delphi Prg
 
Zitat:

Zitat von wschrabi (Beitrag 1367231)
Kann mir da wer sagen, wieso? Ich dachte bei dyn. laden der dll braucht man auf den MemMGR nicht achten?
DANKE für jeden TIPP.

Bitte nicht krumm nehmen, aber Du stocherst hier im Nebel ohne jeden Plan was Du eigentlich tust.

Zuerst einmal: wenn ich den Delphi Teil kompiliere habe ich jeden Menge Warnungen.
Warnungen sind genau dazu da auf mögliche Fehler hinzuweisen.

Dann: Du mixt hier fröhlich unterschiedliche Datentypen durcheinander.
Schauen wir uns das an:
C-Dll:

Code:
char* __declspec(dllexport)__stdcall calcmain(int m_MTCOunt, const char* strInputvec)
ich würde das übersetzen:

Delphi-Quellcode:
function calcmain(m_MTCOunt : integer; const strInputvec : Pansichar) : Pansichar; stdcall;

Deine Deklaration sieht so aus:

Delphi-Quellcode:
function calcmain (MTCount: integer; INputvec: string): string; stdcall;
Das passt nicht!!! Du kannst keine Strings so übergeben. Strings in Delphi sind eine ganz andere Sache als Strings in C++. Die Delphi Strings sind eine Liga für sich und das meine ich positiv. Das ist eine der ganz grossen Stärken. Bevor Du anfängst zu mixen solltest Du dich vieleicht mit den Grundlagen vertraut machen

himitsu 11. Apr 2017 22:21

AW: Call einer DLL von einem Delphi Prg
 
Der Hauptgrund "string" wurde ja bereits genannt.

"String" ist ein Delphi-Typ
und hat nichts mit den C-Strings zu tun.

Außerdem hat "String" oder "PChar" niemals etwas in APIs zu suchen.
Denn das sind dynamische Typen und Schnittstellen sind immer statisch/unveränderlich. (sollten es sein, oder jemand hat geschlafen)
Denn z.B. seit Delphi 2009 sind String/PChar Unicode/Wide und davor waren sie ANSI.
Also in deinem Fall ist es PAnsiChar.



Und wenn du schon dabei bist dir die Grundlagen anzueignen, dann bitte auch das Thema Fehlerbehandlung nicht vernachlässigen.

Delphi-Quellcode:
hmod := LoadLibrary('QMC_DLL.dll');
if (hmod <> 0) then begin

end
else
  ShowMessage('LoadLibrary Failed!');
Es ist schonmal nicht schlecht überhaupt erstmal Fehler zu behandeln,
aber es ist nicht "klug", wenn man den eigentlichen Fehler fahrlässig vernichtet.

Denn warum ist das nun fehlgeschlagen?
Diese APIs geben auch den Grund des Fehlers an. (natürlich nur, wenn es einen Fehler gab)
MSDN-Library durchsuchenLoadLibrary siehe "Return Value"
MSDN-Library durchsuchenGetLastError
Delphi-Quellcode:
else
  RaiseLastOSError;
Delphi-Referenz durchsuchenRaiseLastOSError
Delphi-Quellcode:
else
  ShowMessage('LoadLibrary Failed!' + sLineBreak + ' FehlerCode: ' + IntToStr(GetLastError);
Delphi-Quellcode:
else
  ShowMessage('LoadLibrary Failed!' + sLineBreak + SysErrorMessage(GetLastError));
Falls zwischen der API (z.B. LoadLibrary) und dem GetLastError eine WinAPI aufgerufen werden könnte, dann GetLastError so schnell wie möglich auslesen und zwischenspeichern.
z.B. könnte beim Zusammenbau der davorliegenden Strings Speicher resserviert werden, was ein paar WinAPI-Aufrufe zur Folge hätte.
Delphi-Quellcode:
else
begin
  ErrorCode := GetLastError;
  ShowMessage('LoadLibrary Failed!' + sLineBreak + SysErrorMessage(ErrorCode));
end;
Hier geht es aber zufällig, da vorher nur String-Konstanten liegen und somit IntToStr/SysErrorMessage und GetLastError die ersten Funktionsaufrufe sind.

Für den Entwickler ist es eventuell gibt auch die Fehlerstelle oder den Dateinamen mit auszugeben.
Wenn mal jemand diese Fehlermeldung sieht, dann weißt du gleich wo der Fehler zu suchen ist.

wschrabi 12. Apr 2017 07:02

AW: Call einer DLL von einem Delphi Prg
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke Ihr beiden,
ja das wars ich musste PAnsiChar statt string nehmen.
Ich hatte es schon vorher mit PChar probiert, (komme von Delphi 7 ) daher ging es nicht.
Dann hab ich wieder zu string gewechselt.

Mit PAnsChar klappt es wieder super.

Tausend DANK. :thumb:

himitsu 12. Apr 2017 07:12

AW: Call einer DLL von einem Delphi Prg
 
Dann war aber was noch Anderes falsch :zwinker:, denn
* Delphi 1 bis 2007 : PChar = PAnsiChar
* seit Delphi 2009 : PChar = PWideChar

Zufällig funktioniert es, wenn man im Delphi als IN-Parameter (const) statt PAnsiChar einen AnsiString verwendet, denn intern ist der Delphi-String Binärkompatibel mit PAnsiChar, damit beim Cast
Delphi-Quellcode:
PAnsiChar(EinAnsiString)
praktisch nichts gemacht werden muß.
Das gilt aber nur für Lesezugriffe.

Bei manuellen Header-Übersetzungen nutze ich manchmal gern solch ein Verhalten aus, um die Schnittstellen dann im Programm einfacher (delphi-typischer) nutzen zu können.
String statt PChar zwar nicht so oft, wie es möglich wäre, aber z.B. ein VAR- oder OUT-Parameter statt eines Pointers.

wschrabi 12. Apr 2017 07:24

AW: Call einer DLL von einem Delphi Prg
 
DANKE Dir, wieder viel gelernt.:-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz