Gibt es eine Möglichkeit, meinen Zeiger und meine Größe direkt in einen VarArray-Typ OleVariant zu übergeben, ohne Speicher zu kopieren?
OleVariant
Typ Delphi ist ein Wrapper für VARIANT
Rekord OLE. Der einzige Array-Typ, den OLE unterstützt, ist SAFEARRAY
, und jeder SAFEARRAY
, der von einer Win32 SafeArrayCreate...()
-Funktion erstellt wird, weist den Datenblock zu, auf den er verweist, und besitzt ihn. Sie müssen Ihre Quelldaten in diesen Block kopieren.
Um das zu umgehen, würden Sie VarArrayCreate()
überspringen müssen die SAFEARRAY
selbst und zuweisen (die SafeArrayCreate()
nennt) mit SafeArrayAllocDescriptor/Ex()
so dass es nicht um einen Datenblock zugewiesen werden. Dann können Sie das Feld pvData
des Arrays so einstellen, dass es auf Ihren vorhandenen Speicherblock zeigt, und das FADF_AUTO
Flag in fFeatures
aktivieren, um SafeArrayDestroy()
(OleVariant
Aufrufe, wenn es die SAFEARRAY
nicht mehr benötigt) den Speicherblock nicht freizugeben.
versuchen, etwas wie folgt aus:
uses
..., Ole2, ComObj;
// Delphi's Ole2 unit declares SafeArrayAllocDescriptor()
// but does not declare SafeArrayAllocDescriptorEx()...
function SafeArrayAllocDescriptorEx(vt: TVarType; cDims: Integer; var psaOut: PSafeArray): HResult; stdcall; external 'oleaut32.dll';
function GetVarArrayFromBuffer(ABuffer : pByte; ASizeInBytes: Cardinal) : OleVariant;
var
SA: PSafeArray;
begin
OleCheck(SafeArrayAllocDescriptorEx(VT_UI1, 1, SA));
SA.fFeatures := SA.fFeatures or FADF_AUTO or FADF_FIXEDSIZE;
SA.cbElements := SizeOf(Byte);
SA.pvData := ABuffer;
SA.rgsabound[0].lLbound := 0;
SA.rgsabound[0].cElements := ASizeInBytes;
TVarData(Result).VType := varByte or varArray;
TVarData(Result).VArray := PVarArray(SA);
end;
Wenn Sie nicht wirklich OLE verwenden müssen, wie zum Beispiel, wenn Sie nicht zu anderen Menschen die Anwendungen über OLE Array sind vorbei, dann sollten Sie die Verwendung Delphi Variant
Typ stattdessen. Sie können eine Custom Variant Type
schreiben, um alle gewünschten Daten zu speichern, sogar einen Verweis auf Ihren vorhandenen Speicherblock, und dann Variant
nach Bedarf verwenden und Ihre benutzerdefinierte Implementierung die Daten nach Bedarf verwalten lassen.
Vielen Dank. –