加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 我可以从缓冲区(pByte)和大小创建VarArray OleVariant

发布时间:2020-12-15 04:14:15 所属栏目:大数据 来源:网络整理
导读:我可以将内存从缓冲区复制到安全数组中,如下所示 function GetVarArrayFromBuffer(ABuffer : pByte; ASizeInBytes: Cardinal) : OleVariant; var LVarArrayPtr: Pointer; begin Result := VarArrayCreate([0,ASizeInBytes - 1],varByte); LVarArrayPtr := Va
我可以将内存从缓冲区复制到安全数组中,如下所示
function GetVarArrayFromBuffer(ABuffer : pByte; ASizeInBytes: Cardinal) : OleVariant;
  var
    LVarArrayPtr: Pointer;     
  begin
    Result := VarArrayCreate([0,ASizeInBytes - 1],varByte);
    LVarArrayPtr := VarArrayLock(Result);
    try
      Move(ABuffer^,LVarArrayPtr^,ASizeInBytes);
    finally
      VarArrayUnLock(Result);
    end;
  end;

但是,有没有办法直接将我的指针和大小传递给varArray类型OleVariant而不复制内存?

[编辑]

我可以看到OleVariant中的数组是一个SAFEARRAY(定义为PVarArray = ^ TVarArray),所以看起来应该有一种方法可以通过填充TVarArray中的值并在OleVariant中设置VType和VArray值来实现这一点. .

解决方法

is there a way to directly pass my pointer and size into a varArray type OleVariant without copying memory?

Delphi的OleVariant类型是OLE VARIANT记录的包装器. OLE支持的唯一类型的数组是SAFEARRAY,并且由Win32 SafeArrayCreate …()函数创建的任何SAFEARRAY都会分配并拥有它指向的数据块.您必须将源数据复制到该块中.

要绕过它,你必须跳过VarArrayCreate()(它调用SafeArrayCreate())并使用SafeArrayAllocDescriptor / Ex()自己分配SAFEARRAY,这样它就不会分配数据块.然后,您可以将数组的pvData字段设置为指向现有内存块,并在其fFeatures字段中启用FADF_AUTO标志,以告知SafeArrayDestroy()(当OleVariant不再需要SAFEARRAY时调用它)不释放内存块.

尝试这样的事情:

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;

如果您实际上不需要使用OLE,例如,如果您没有通过OLE将数组传递给其他人的应用程序,那么您应该使用Delphi的Variant类型.您可以编写一个Custom Variant Type来保存您想要的任何数据,甚至是对现有内存块的引用,然后根据需要使用Variant,并让您的自定义类型实现根据需要管理数据.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读