AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Call einer DLL von einem Delphi Prg

Ein Thema von wschrabi · begonnen am 11. Apr 2017 · letzter Beitrag vom 12. Apr 2017
Antwort Antwort
wschrabi

Registriert seit: 16. Jan 2005
256 Beiträge
 
#1

Call einer DLL von einem Delphi Prg

  Alt 11. Apr 2017, 20:50
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
Angehängte Dateien
Dateityp: zip dll_QMC.zip (67,4 KB, 3x aufgerufen)

Geändert von wschrabi (11. Apr 2017 um 21:27 Uhr)
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
628 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#2

AW: Call einer DLL von einem Delphi Prg

  Alt 11. Apr 2017, 21:34
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:

function calcmain(m_MTCOunt : integer; const strInputvec : Pansichar) : Pansichar; stdcall;
Deine Deklaration sieht so aus:

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
Fritz Westermann
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
34.931 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: Call einer DLL von einem Delphi Prg

  Alt 11. Apr 2017, 22:21
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu (11. Apr 2017 um 22:32 Uhr)
  Mit Zitat antworten Zitat
wschrabi

Registriert seit: 16. Jan 2005
256 Beiträge
 
#4

AW: Call einer DLL von einem Delphi Prg

  Alt 12. Apr 2017, 07:02
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.
Angehängte Dateien
Dateityp: zip QMC_dll_ok.zip (27,2 KB, 1x aufgerufen)

Geändert von wschrabi (12. Apr 2017 um 09:02 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
34.931 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: Call einer DLL von einem Delphi Prg

  Alt 12. Apr 2017, 07:12
Dann war aber was noch Anderes falsch , 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 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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu (12. Apr 2017 um 07:14 Uhr)
  Mit Zitat antworten Zitat
wschrabi

Registriert seit: 16. Jan 2005
256 Beiträge
 
#6

AW: Call einer DLL von einem Delphi Prg

  Alt 12. Apr 2017, 07:24
DANKE Dir, wieder viel gelernt.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 16:02 Uhr.
Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf