AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi DLL Exportiert ein Interface mit Strings...
Thema durchsuchen
Ansicht
Themen-Optionen

DLL Exportiert ein Interface mit Strings...

Ein Thema von Mavarik · begonnen am 9. Jun 2014 · letzter Beitrag vom 9. Apr 2017
Antwort Antwort
Seite 4 von 4   « Erste     234   
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
961 Beiträge
 
Delphi 6 Professional
 
#31

AW: DLL Exportiert ein Interface mit Strings...

  Alt 9. Apr 2017, 18:26
Hmm..

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


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
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.330 Beiträge
 
Delphi 11 Alexandria
 
#32

AW: DLL Exportiert ein Interface mit Strings...

  Alt 9. Apr 2017, 18:56
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.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
wschrabi

Registriert seit: 16. Jan 2005
437 Beiträge
 
#33

AW: DLL Exportiert ein Interface mit Strings...

  Alt 9. Apr 2017, 19:10
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
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#34

AW: DLL Exportiert ein Interface mit Strings...

  Alt 9. Apr 2017, 19:33
Hallo,
wie bereits geschrieben,
muss der Aufrufer der Dll den Speicher reservieren (GetMem)

Die DLL-Funktion muss strncpy benutzen.
Heiko

Geändert von hoika ( 9. Apr 2017 um 19:36 Uhr)
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#35

AW: DLL Exportiert ein Interface mit Strings...

  Alt 9. Apr 2017, 21:13
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
  Mit Zitat antworten Zitat
wschrabi

Registriert seit: 16. Jan 2005
437 Beiträge
 
#36

AW: DLL Exportiert ein Interface mit Strings...

  Alt 9. Apr 2017, 21:20
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?

  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

Geändert von wschrabi ( 9. Apr 2017 um 21:38 Uhr)
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#37

AW: DLL Exportiert ein Interface mit Strings...

  Alt 9. Apr 2017, 21:26
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

Geändert von mensch72 ( 9. Apr 2017 um 21:28 Uhr)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#38

AW: DLL Exportiert ein Interface mit Strings...

  Alt 9. Apr 2017, 21:30
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
Heiko

Geändert von hoika ( 9. Apr 2017 um 21:36 Uhr)
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#39

AW: DLL Exportiert ein Interface mit Strings...

  Alt 9. Apr 2017, 21:33
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
  Mit Zitat antworten Zitat
wschrabi

Registriert seit: 16. Jan 2005
437 Beiträge
 
#40

AW: DLL Exportiert ein Interface mit Strings...

  Alt 9. Apr 2017, 21:43
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;
}
Miniaturansicht angehängter Grafiken
schroot.gif  

Geändert von wschrabi ( 9. Apr 2017 um 22:27 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 4   « Erste     234   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:47 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