Delphi-PRAXiS
Seite 4 von 4   « Erste     234   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi DLL Exportiert ein Interface mit Strings... (https://www.delphipraxis.net/180689-dll-exportiert-ein-interface-mit-strings.html)

HolgerX 9. Apr 2017 18:26

AW: DLL Exportiert ein Interface mit Strings...
 
Hmm..

Schaue Dir mal die Deklarationen von deiner App und der DLL an:

Zitat:

Zitat von wschrabi (Beitrag 1366920)

function calcsum(a: double; b: double):integer ; cdecl; external 'qmc_dll_Project1.dll';
procedure calcmain( var loesung: Pansichar) ; cdecl; external 'qmc_dll_Project1.dll';
procedure calcmaindummy( var loesung: PansiChar) ; cdecl; external 'qmc_dll_Project1.dll';

...


extern int __declspec(dllexport) __stdcall calcsum(double a, double b){
return a + b;
}

extern void __declspec(dllexport) __stdcall calcmaindummy(char* loesungdummy)
{
loesungdummy = "TESTENDE:2ndLine"; //resultbuff;

}
[/DELPHI]


Ich tippe auf das 'cdecl' statt des 'stdcall' in der DLL ;)

jaenicke 9. Apr 2017 18:56

AW: DLL Exportiert ein Interface mit Strings...
 
Außerdem wäre es sauberer, wenn die DLL den Speicher nicht selbst reservieren würde, sondern die Hauptanwendung den Speicher reserviert und den Pointer plus die Größe des Bereiches an die DLL übergibt.

Dazu gegebenenfalls vorher noch die Anfrage an die DLL wie viel Speicher benötigt wird. Also analog zur API von Windows.

wschrabi 9. Apr 2017 19:10

AW: DLL Exportiert ein Interface mit Strings...
 
Zitat:

Ich tippe auf das 'cdecl' statt des 'stdcall' in der DLL ;)
Nein hab ich schon alles probiert.
Hab gelesen dass man da memmgr.lib dazu linken muss.
WIe muss ich das machen? Hab schon Bei den Programmoptionen "Mit Laufzeitbibliothek linken" auf true gesetzt.

Kann mir einfach ein Bsp geben wie man einen String zurückgibt?
Ich sitz jetzt schon Stunden hier und komm nicht weiter....

DANKE
WS

hoika 9. Apr 2017 19:33

AW: DLL Exportiert ein Interface mit Strings...
 
Hallo,
wie bereits geschrieben,
muss der Aufrufer der Dll den Speicher reservieren (GetMem)

Die DLL-Funktion muss strncpy benutzen.

mensch72 9. Apr 2017 21:13

AW: DLL Exportiert ein Interface mit Strings...
 
ganz allgemein: in DLLs gib im WIN-API es keine "void"/"procedure", man verwende besser immer "function" und gebe IMMER mindestens einen "integer" zurück

wenn es unbedingt var sein soll, dann so:
function calcmaindummy( var loesung: PansiChar):integer ; cdecl; external 'qmc_dll_Project1.dll';
extern integer __declspec(dllexport) __stdcall calcmaindummy(char** loesungdummy)

*loesungdummy="irgendwas"; // die Rückgabe MUSS ein konstanter oder globaler statischer Speicherbereich sein, keine lokale Variable, weil die ist weg wenn die Funktion zu Ende!!!
return(0);


oder einfacher:
function calcmaindummy(): PAnsiChar ; cdecl; external 'qmc_dll_Project1.dll';
extern char* __declspec(dllexport) __stdcall calcmaindummy(void)

return("irgendwas"); // die Rückgabe MUSS ein konstanter oder globaler statischer Speicherbereich sein, keine lokale Variable, weil die ist weg wenn die Funktion zu Ende!!!





etwas tricky, aber Delphi seitig sehr sicher:
im DelphiProgramm einen PAnsiChar auf einen ShortString übergeben und den in der C-DLL per "strcpy" füllen

function calcmaindummy(loesung: PansiChar):integer ; cdecl; external 'qmc_dll_Project1.dll';
extern integer __declspec(dllexport) __stdcall calcmaindummy(char* loesungdummy)

strcpy(&loesungdummy[1],"irgendwas");
loesungdummy[0]=strlen(&loesungdummy[1]);
return(0);


delphi:
var loesung:shortstring;

calcmaindummy(@loesung); // blind getippt, aber des sollte nach Gefühl ohne Cast so gehen

wschrabi 9. Apr 2017 21:20

AW: DLL Exportiert ein Interface mit Strings...
 
danke dir.
Meinst du so?
Delphi-Quellcode:
function calcsum(a: double; b: double):integer ; stdcall; external 'qmc_dll_Project1.dll';
procedure calcmain( var loesung: Pansichar) ; stdcall; external 'qmc_dll_Project1.dll';
procedure calcmaindummy( var loesung: PANsiChar) ; stdcall; external 'qmc_dll_Project1.dll';

procedure TForm1.Button1Click(Sender: TObject);
var
    loesung: PAnsiChar;

begin
    ShowMessage(inttostr(calcsum(1,2)));
    getmem(loesung,300);
    calcmaindummy(loesung);

    ShowMessage(String(loesung));
end;
und in dll:
Code:
void __declspec(dllexport) __stdcall calcmaindummy(char* loesung){

strcpy(loesung,"TESTENDE:2ndLine"); //resultbuff;

}
oder muss ich in Delphi die Adresse übergeben?

Delphi-Quellcode:
  calcmaindummy(@loesung);
Dann meckert er beim compiliern.

Habs jetzt dyn geladen und da komm tauch nur Schrott zurück:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  hmod : THandle;
  GetReturn : procedure ( var loesung: PANsiChar) ; stdcall;
  RetStr : PAnsichar;
begin
  hmod := LoadLibrary('qmc_dll_Project1.dll');
  if (hmod <> 0) then begin
    GetReturn := GetProcAddress(hmod, 'calcmaindummy');
    if (@GetReturn <> nil) then begin
      GETMEM(RetStr,20);
      GetReturn(RetStr);
      ShowMessage('Drive Type is : ' + string(RetStr));
    end
    else
      ShowMessage('GetProcAddress failed');
    FreeLibrary(hmod);
  end
  else
    ShowMessage('LoadLibrary Failed!');
end;
Ich galub das hat mit dem MEMMGR.LIB zu tun. MUss man da was machen oder wie?

DANKE
mfg
ws

mensch72 9. Apr 2017 21:26

AW: DLL Exportiert ein Interface mit Strings...
 
für deine Variante mit GetMem wäre der C teil so:

strcpy(loesungdummy,"irgendwas");
return(0);


Ich bleibe Dabei: man macht in DLLs keine proceduren/void Rückgaben... wenn MicroSoft das gewollt hätte, hätten die das im WinApi selbst auch gemacht... haben sie aber nicht... also geben man eben auch immer etwas ala integer zurück:)

hoika 9. Apr 2017 21:30

AW: DLL Exportiert ein Interface mit Strings...
 
Hallo,
char* = PAnsiChar

Das var kannst du also weglassen.

strncpy und nicht strcpy benutzen

Was soll eigentlich des decl?
siehe auch hier
http://stackoverflow.com/questions/2...need-to-use-it

mensch72 9. Apr 2017 21:33

AW: DLL Exportiert ein Interface mit Strings...
 
wenn schon "strncpy", dann bitte aber auch die mögliche MaxLänge mit als Parameter übergeben, sonst weiß das C Programm ja nicht wieviel Speicher wirklich der Aufrufer zu Verfügung gestellt hat... dann wird es erst sicherer:)

wschrabi 9. Apr 2017 21:43

AW: DLL Exportiert ein Interface mit Strings...
 
Liste der Anhänge anzeigen (Anzahl: 1)
es klappt einfach nicht.
Es kommt Schrott.. (sieh bild)

Jetzt hab ich mal eine int via return (= summe) das klappt.
ABer die integer via return in den formalen paramters klappt nicht.

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  hmod : THandle;
  GetReturn : procedure ( var loesung: integer) ; stdcall;
  Getsum:    function ( a: double; b: double; c: double):integer ; stdcall;
  RetStr : PAnsichar;
  RetINT: integer;
begin
  hmod := LoadLibrary('qmc_dll_Project1v2.dll');
  if (hmod <> 0) then begin
    GetReturn := GetProcAddress(hmod, 'calcmaindummy');
    if (@GetReturn <> nil) then begin
      GETMEM(RetStr,20);
      //GetReturn(RetStr);
      GetReturn(Retint);
      ShowMessage('Loeung des QMC ist : ' + inttostr(Retint));
    end
    else
      ShowMessage('GetProcAddress failed');
    GetSUM := GetProcAddress(hmod, 'calcsum');
    if (@GetSUM <> nil) then begin
      ShowMessage('Summe ist : ' + inttostr(GetSUM(9,2,1)));
    end
    else
      ShowMessage('GetProcAddress failed');
    FreeLibrary(hmod);
  end
  else
    ShowMessage('LoadLibrary Failed!');
end;
mit dem ohne __cdecl(..) geht es nicht.

Da findet er die function mit dem dyn laden nicht mehr.
Code:
void __stdcall calcmaindummy(int loesung){
   char* demotest = "KTestende:2ndline";

   //strncpy(loesung,demotest,5); //resultbuff;
   loesung = 3;
   return 0;

}
also doch so:
Code:
void __declspec(dllexport)__stdcall calcmaindummy(int loesung){
   char* demotest = "KTestende:2ndline";

   //strncpy(loesung,demotest,5); //resultbuff;
   loesung = 3;
   return 0;

}

int __declspec(dllexport) __stdcall calcsum(double a, double b, double c){
   return a +b +c;
}


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:20 Uhr.
Seite 4 von 4   « Erste     234   

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