![]() |
COM-Objekt und Pointer-Type
Hallo!
Ich muss an ein Com-Objekt einen Pointer auf Daten übergeben. Delphi macht aus der Definition aber immer einen var-Pointer, in der TLB scheint es richtig zu sein. Wenn ich ein Com-Interface definiere und einen Parameter mit "void *" angeben und die erzeugte DLL mit einem TLB-Viewer anschau sehe ich:
Delphi-Quellcode:
Das scheint also zu passen. Wenn ich in den Delphi-Settings von IDL auf Pascal umschalte, sehe ich "Pointer" - passt also. (Aber eintippen kann ich "Pointer" so nicht, das verweigert der TypeLib-Editor).
HRESULT WriteData(
[in] long SampleNum, [in] void* PData); In der ..._TLB.pas Datei steht an solchen Stellen dann aber immer
Delphi-Quellcode:
Das "var" ist da falsch. Das ist ja ein Pointer auf einen Pointer, ist dann aber nicht in der Variable drin.
var PData: Pointer
Da müsste korrekterweise stehen:
Delphi-Quellcode:
Wie krieg ich das am besten hin? Einen anderen Datentypen wie z.B. integer nehmen und casten find ich unintuitiv (wenn man die Interface-Definition liest und ich sehe "PData : integer" wüsste ich nicht auf Anhieb was da zu tun ist).
procedure WriteData(MyNumber: Integer; MyPointer: Pointer); safecall;
Gibt's vernünftig unterstützte COM-Pointertypen? Danke. |
Re: COM-Objekt und Pointer-Type
Bei COM müssen ja Daten teilweise über Prozessgrenzen hinweg transportiert werden.
Und da wird es bei einem Zeiger ja sehr problematisch, da dieser Zeiger in einem anderen Prozess auf etwas völlig anderes zeigt. Man kann deshalb nur Datenblöcke über Prozessgrenzen tranportieren. Wenn das COM-System weiss, dass die Daten bei Adresse XY beginnen und sagen wir 500 Bytes lang sind, dann kann man ja diesen Speicherblock kopieren und/oder im Zielprozess einblenden. Bei DCOM werden die Daten übers Netzwerk verschickt. Deshalb verpackt man binäre Daten häufig in einem Variant-Array vom Typ varByte.
Delphi-Quellcode:
Man erkennt an deinem Sourcecode nicht genau, was du tun möchtest; irgendetwas mit Samples.
function VarByteArrayCreate(const Data; len:Integer):Variant;
var vdata : Pointer; begin if len > 0 then begin Result := VarArrayCreate([0, len-1], varByte); vdata := VarArrayLock(Result); try Move(Data, vdata^, len); finally VarArrayUnlock(Result); end; end else Result := Null; end; Wenn du jedes einzelne Sample über eine COM Funktion schicken möchtest, dann musst du etwas umdenken und stattdessen den gesamten Samplebuffer in einem OleVariant verpackt versenden. |
Re: COM-Objekt und Pointer-Type
Zitat:
Daher meine Frage nach einem einfachen Pointer-Typen. Wenn ich PChar nehme, macht da Delphi irgendeinen Compiler-Magic der mir Probleme bereiten könnte, wenn da gar kein PChar daherkommt, sondern ich das einfach als normalen Pointer missbrauche? Sprich, in der Methode:
Delphi-Quellcode:
Würde das gehen?
procedure WriteData(MyNumber: Integer; PData_ : PChar); safecall;
var PData : Pointer; begin PDate:=PData_; ... und hier dann normal weiterarbeiten... |
Re: COM-Objekt und Pointer-Type
Zitat:
Bei Delphi ist man mit COM etwas eingeschränkt auf den Standard-Marshaller von Windows. Und wenn dieser das entsprechende nicht kann, kann es Delphi auch. Hierzu müßtest du z.B. Visual C++ nehmen da du hier "einfach" deinen eigenen Marshaler schreiben kannst. |
Re: COM-Objekt und Pointer-Type
Zitat:
Es funktioniert ja auch prächtig, nur konvertiert Delphi die TLBs falsch. Wie gesagt, statt "Pointer" steht da "var Pointer". Wenn man das händisch korrigiert läuft alles prima. Nur blöderweise verhunzt Delphi die _TLB.pas - Files dann immer sobald man was mit dem Typelib-Editor macht. |
Re: COM-Objekt und Pointer-Type
Du kannst ohne Probleme PChar verwenden. Es ist einfach nur ein typisierter Pointer. Natürlich solltest du kommentieren, um was es sich wirklich bei den Daten handelt.
Meist sollte man zum Pointer auch noch eine Größenangabe ansetzen, falls die Daten dynamisch sind. Alles andere könnte auch Bufferoverflows ergeben. Für OutOfProcess gibt es die Möglichkeit von IStream. Hier kann man ganz einfach beliebige Daten marshallen lassen. |
Re: COM-Objekt und Pointer-Type
Zitat:
Werd' ich gleich machen, dann hat die Quälerei endlich ein Ende... P.S.: Das mit der Grössenangabe mach ich sowieso, da die Plugins manchmal den Speicher wieder freigeben müssen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:38 Uhr. |
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