Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi COM-Objekt und Pointer-Type (https://www.delphipraxis.net/112496-com-objekt-und-pointer-type.html)

ralfiii 22. Apr 2008 12:59


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:
HRESULT WriteData(
                [in] long SampleNum,
                [in] void* PData);
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).

In der ..._TLB.pas Datei steht an solchen Stellen dann aber immer
Delphi-Quellcode:
  var PData: Pointer
Das "var" ist da falsch. Das ist ja ein Pointer auf einen Pointer, ist dann aber nicht in der Variable drin.
Da müsste korrekterweise stehen:
Delphi-Quellcode:
    procedure WriteData(MyNumber: Integer; MyPointer: Pointer); safecall;
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).

Gibt's vernünftig unterstützte COM-Pointertypen?

Danke.

shmia 22. Apr 2008 15:35

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:
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;
Man erkennt an deinem Sourcecode nicht genau, was du tun möchtest; irgendetwas mit Samples.
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.

ralfiii 22. Apr 2008 15:44

Re: COM-Objekt und Pointer-Type
 
Zitat:

Zitat von shmia
Bei COM müssen ja Daten teilweise über Prozessgrenzen hinweg transportiert werden.

Stimmt schon, aber in meinem Fall sind es ausschliesslich In-Process Com-Objekte, und dafür wirklich riesige Datenmengen die ich auf keinen Fall umkopieren möchte.
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:
procedure WriteData(MyNumber: Integer; PData_ : PChar); safecall;
var PData : Pointer;
begin
     PDate:=PData_;
     ... und hier dann normal weiterarbeiten...
Würde das gehen?

Bernhard Geyer 22. Apr 2008 15:53

Re: COM-Objekt und Pointer-Type
 
Zitat:

Zitat von ralfiii
Zitat:

Zitat von shmia
Bei COM müssen ja Daten teilweise über Prozessgrenzen hinweg transportiert werden.

Stimmt schon, aber in meinem Fall sind es ausschliesslich In-Process Com-Objekte, und dafür wirklich riesige Datenmengen die ich auf keinen Fall umkopieren möchte.
Daher meine Frage nach einem einfachen Pointer-Typen.

Wieso verwendest du überhaupt COM?
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.

ralfiii 22. Apr 2008 17:25

Re: COM-Objekt und Pointer-Type
 
Zitat:

Zitat von Bernhard Geyer
Wieso verwendest du überhaupt COM?

Schien mir eine gute Idee, weil man die Anwendung so gut Script-steuern kann und auch in anderen Sprachen recht gemütlich Plugins für unsere Anwendung schreiben kann.
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.

Dezipaitor 22. Apr 2008 19:24

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.

ralfiii 22. Apr 2008 20:38

Re: COM-Objekt und Pointer-Type
 
Zitat:

Zitat von Dezipaitor
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.

Super, danke!
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 13:23 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