Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Problem String (PAnsiChar) Parameter in Com Server Anwendung (https://www.delphipraxis.net/143369-problem-string-pansichar-parameter-com-server-anwendung.html)

ekke 14. Nov 2009 13:17


Problem String (PAnsiChar) Parameter in Com Server Anwendung
 
Hallo,
ich habe ein Problem mit der Rückgabe eines Strings über eine Com-Schnittstelle.
Der Com-Server ist ein Out-Of-Process Server (also eine eigene Anwendung). Die Client instantiert den Server und verdendet die Funktionen der Schnittstelle. Funktioniert alles prima - bis auf...

Ich habe eine Methode im Type Library Editor deklariert, die als einen IN Parameter einen String (LPSTR, übersetzt in PChar) übergibt. Einen weiteren Parameter als OUT der einen String (*LPSTR, übersetzt var PChar) zurück geben soll.
Also in etwa Methode
function MyComServer.GetVorname(Nachname : PChar; var Vorname : PChar) : HRESULT;safecall;
begin
Vorname := PChar(AObjectGlobalStr);
Result := S_OK;
end;

AObjectGlobalStr ist ein normaler String der in der private section der Klasse deklariert ist und einen geeigneten Wert enthält.

Wenn ich die Funktion aufrufe wird alles ausgeführt, es kommt aber *nach* dem Verlassen der Funktion offensichtlich zu einer exception, da der Debugger das CPU/Disassembler Fenster öffnet. Der Client bekommt das richtige Ergebnis zu sehen, bemerkt also von der Exception nichts.

Während der Laufzeit (ohne Debugger) sieht alles ganz normal aus, außer das mit jedem Aufruf etwas Speicher verwendet wird der nicht wieder freigegeben wird, d.h. nach einer Nacht intensiven Rennens sind einige hundert MB verbraucht.

Ich habe die Variante mit PChar verwenden wollen um das gehample mit den SafeArrays zu umgehen, oder darf man das so einfach nicht machen?

Gruß Ekkehard

Apollonius 14. Nov 2009 13:26

Re: Problem String (PAnsiChar) Parameter in Com Server Anwen
 
Das kann allein aufgrund des Speichermanagements nicht funktionieren. Warum nimmst du nicht Widestring, wie es bei COM üblich ist?

ekke 14. Nov 2009 17:40

Re: Problem String (PAnsiChar) Parameter in Com Server Anwen
 
Danke für die Antwort. Ich kann natürlich WideString verwenden, würde denn das das Problem lösen?
Gruß Ekkehard

Bernhard Geyer 14. Nov 2009 19:29

Re: Problem String (PAnsiChar) Parameter in Com Server Anwen
 
Zitat:

Zitat von ekke
Ich kann natürlich WideString verwenden, würde denn das das Problem lösen?

Ja. Der Standard-COM Marshaller sorgt dafür das die Daten vom Adressraum der einen Anwendung in den anderen Anwendung tranferiert werden.

ekke 16. Nov 2009 13:17

Re: Problem String (PAnsiChar) Parameter in Com Server Anwen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Vorneweg, es geht auch mit WideChar nicht :-(
Ich habe mal ein kleines Testprogramm gebastelt, um die Details zu erforschen.
Ich vermute, das die Rückgabe mittels PChar/PWideChar nicht gehen kann, weil die Datenlänge dynamisch ist. Ist halt seltsam das die Daten tatsächlich ohne Fehler übertragen werden.

Zum Nachvollziehen: Beide Apps kompilieren, dann den Server in Delphi starten, Break point in die beiden Proceduren setzen, den Client starten und jeweils einen Button (Button1, Button2) betätigen.
Nach Verlassen der Server procedure(n) kommt das CPU Fenster hoch, mit F9 weiterlaufen lassen, Ergebnis steht im Client

Achso: Compiler D7 prof.
D2009 zeigt das gleiche Verhalten, allerdings hatte ich dort die "ein Byte"-Variante auskommentiert, also nur die WideChar variante probiert

Server Code

Delphi-Quellcode:
  TCharServer = class(TAutoObject, ICharServer)
  private
    TheReturnString : String;
    TheReturnWString : WideString;
...

Delphi-Quellcode:
procedure TCharServer.GetPChar(InputValue: PChar; out OutputValue: PChar);
begin
  TheReturnString := FormatDateTime('HH:nn:ss-zzz',Now);
  OutputValue := PAnsiChar(TheReturnString);
end; // <<----- hier passiert der Fehler (Debugger CPU Fenster)

procedure TCharServer.GetPWideChar(InputValue: PWideChar;
  out OutputValue: PWideChar);
begin
  TheReturnWString := FormatDateTime('HH:nn:ss-zzz',Now);
  OutputValue := PWideChar(TheReturnWString);
end; // <<----- hier passiert der gleiche Fehler (Debugger CPU Fenster)
Client Code

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  FServer := CoCharServer.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  p : PAnsiChar;
begin
  p := Nil;
  FServer.GetPChar('Hallo',p);
  if Assigned(p) then
    Memo1.Lines.Add(p)
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  p : PWideChar;
begin
  p := Nil;
  FServer.GetPWideChar('Hallo',p);
  if Assigned(p) then
    Memo1.Lines.Add(p)
end;
Gruß Ekkehard

Bernhard Geyer 16. Nov 2009 13:21

Re: Problem String (PAnsiChar) Parameter in Com Server Anwen
 
Zitat:

Zitat von ekke
Vorneweg, es geht auch mit WideChar nicht :-(

Und wieso verwendest du keinen WideString wie du bei deinem Letzten Post gefragt hast :gruebel:

PChar ist wieder ein Zeiger der nicht über Prozessgrenzen hinaus gültig ist!

ekke 16. Nov 2009 14:53

Re: Problem String (PAnsiChar) Parameter in Com Server Anwen
 
Hmmmm...
So baut Delphi das aus dem Type Library Editor (LPWSTR *) zusammen:

Delphi-Quellcode:
    procedure GetPWideChar(InputValue: {??PWideChar}OleVariant;
                           out OutputValue: {??PWideChar}OleVariant); dispid 202;
und so ist es implementiert

Delphi-Quellcode:
    TheReturnWString : WideString;
...
procedure TCharServer.GetPWideChar(InputValue: PWideChar;
  out OutputValue: PWideChar);
begin
  TheReturnWString := FormatDateTime('HH:nn:ss-zzz',Now);
  OutputValue := PWideChar(TheReturnWString);
end;

Was habe ich übersehen?

Bernhard Geyer 16. Nov 2009 15:57

Re: Problem String (PAnsiChar) Parameter in Com Server Anwen
 
Zitat:

Zitat von ekke
So baut Delphi das aus dem Type Library Editor (LPWSTR *) zusammen:

Änderen dein Typlib-Definition. Mit Delphi kannst du keine PChars über Prozessraumgrenzen übertragen! Hierzu ist ein Custom-Marshaller nötig den du AFAIK nicht mit Delphi erzeugen kannst. Du bist auf das angewiesen was der COM-Standard-Marshaller kann. Und dieser kann keine P(Wide)Chars entsprechend behandeln.

ekke 16. Nov 2009 17:07

Re: Problem String (PAnsiChar) Parameter in Com Server Anwen
 
Ok, dann kann ich keine Strings über die Com-Schnittstelle von einer Anwendung zur Anderen übertragen, weil es keinen Typ gibt, den ich im Type Library Editor auswählen kann.

Danke für die Hilfe :-)

Bernhard Geyer 16. Nov 2009 17:38

Re: Problem String (PAnsiChar) Parameter in Com Server Anwen
 
Zitat:

Zitat von ekke
Ok, dann kann ich keine Strings über die Com-Schnittstelle von einer Anwendung zur Anderen übertragen, weil es keinen Typ gibt, den ich im Type Library Editor auswählen kann.

Komisch nur das ich das permanent mache :gruebel:

Auf Ebene von IDL wäre der zu verwendente Typ "BSTR", Auf Ebene von Pascal "WideString"


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:34 Uhr.
Seite 1 von 2  1 2      

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