Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi BSTR* als Parameter für externe DLL? (https://www.delphipraxis.net/153126-bstr%2A-als-parameter-fuer-externe-dll.html)

pantarhei 22. Jul 2010 08:30

BSTR* als Parameter für externe DLL?
 
Hallo allerseits,

ich habe eine exteren DLL die mir folgende Funktion zur Verfügung stellt:

Code:
extern "C" int __cdecl GetTemplate(BSTR* bstrTemplate, LONG* lRetCode);
Ich habe die Funktion folgendermassen in D7 deklariert:

Code:
function GetTemplate(ATemplate: PWideString; var ARetCode: Longint): Integer; cdecl; external 'Template.dll';
Verwendet wird das Ganze dann folgendermassen in einer Klasse die von TThread erbt:

Aufruf des Threads:

Code:
  templateThread := TScanThread.Create(false);
  threadResult := templateThread.WaitFor;
Verwendung der externen DLL:

Code:
procedure TTemplateThread.Execute;
begin
  try
    GetTemplate;
 
    ReturnValue := 1;
  except
    on ex: Exception do
      logger.Error(ex.Message);
  end;
end;
Code:
function TTemplateThread.GetTemplate: String;
var
  template: PWideString;
  retCode: Longint;
begin
  New(template);

  GetTemplate(template, retCode);

  //logger.Info('Template: ' + template^);

  Dispose(scanData);

  Result := '';
end;
So wie oben beschrieben funktioniert das Ganze auch ohne Fehler. Wenn ich jetzt allerdings in der GetTemplate Methode den Kommentar entferne und per template^ auf den zurückgegebenen Wert zugreife, wird dieser auch wunderbar geloggt. Funktioniert also im Prinzip wie es soll. Allerdings erhalte ich dann eine Access violation wenn auf ReturnValue in der Execute Methode zugegriffen wird.

Warum erhalte ich eine Access Violation in der Execute Methode soblad ich den Zeiger in der GetTemplate Funktion dereferenziere? Gibt es da einen generellen Denkfehler? Steige gerade nicht durch.

Jemand eine Idee?

Gruss, Daniel

himitsu 22. Jul 2010 08:44

AW: BSTR* als Parameter für externe DLL?
 
varsuch mal
Delphi-Quellcode:
function GetTemplate(var ATemplate: WideString; var ARetCode: Longint): Integer; cdecl;
  external 'Template.dll';
Delphi-Quellcode:
function TTemplateThread.GetTemplate: String;
var
  template: WideString;
  retCode: Longint;
begin
  GetTemplate(template, retCode);
  //logger.Info('Template: ' + template);
  Result := template;
end;
Und vielleicht noch retCode mit auswerten.

pantarhei 22. Jul 2010 08:54

AW: BSTR* als Parameter für externe DLL?
 
So habe ich es auch schon getestet. Dann taucht der Fehler nicht auf. Also der Thread läuft zu Ende so wie er soll, mit dem entsprechenden ReturnValue. Allerdings ist template immer leer. retCode ist 0, was laut Dokumentation der DLL bedeutet dass der Aufruf erfolgreich war.

retCode = 0 ist auch der Fall wenn ich es so mache wie zuerst beschrieben. Dann kann ich aber eben zumindest lesen was ich zurückbekomme. Also scheint der PWideString schon die richtige Variante zu sein.

pantarhei 27. Jul 2010 11:28

AW: BSTR* als Parameter für externe DLL?
 
Das Problem lag wohl daran dass ich einen Thread verwendet habe. Die externe DLL scheint aber schon intern in einem Thread zu arbeiten. Zumindest kann ich die Funktion der DLL aufrufen ohne dass irgendetwas blockiert wird. Die Fenster der DLL werden modal über meiner Anwendung angezeigt, aber meine Anwendung wird trotzdem aktualisiert. Also es wird z.B. alles wird gezeichnet beim Fensterwechsel. Scheint also irgendwo Probleme mit beim Context oder was auch immer gegeben zu haben. Funktioniert jetzt aufjedenfall ohne Thread. ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:13 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