【问题标题】:Delphi COM Passing ByteArray as OleVariantDelphi COM 将 ByteArray 作为 OleVariant 传递
【发布时间】:2014-03-12 07:39:31
【问题描述】:

我正在通过 COM 连接指纹读取器,我需要帮助将 VB.NET 和 C++ 代码转换为 Delphi。

API 以 olevariant 作为参数:

Function FingerPrint.GetData(var ImageData : OleVariant) : WordBool;

提供的 VB.NET 示例:

Dim imgData() as Byte
ReDim imgData(fingerPrint.ImageSize) as Byte

If fingerPrint.GetData(imgData) = True Then  
   'Success
End If

提供的 C++ 示例:

BYTE* dataBuff = new BYTE[fingerPrint.ImageSize];
VARIANT imgData;

imgData.vt = VT_BYREF|VT_UI1;
imgData.pbVal = dataBuff;

if(fingerPrint.getData(imgData) == TRUE) {
  //Success
}

这是我的 Delphi 代码:

procedure GetImgData();
var varBuffer : OleVariant;
    imgBuff : PByteArray;
begin
     GetMem(imgBuff, fingerPrint.ImageSize);

     try
        tagVariant(varBuffer).vt    := VT_UI1 or VT_BYREF; // 0x4011
        tagVariant(varBuffer).pbVal := Pointer(imgBuff);

        if fingerPrint.getData(varBuffer) then
        begin
             // success
        end;
     finally
        FreeMem(imgBuff);
     end;
end;

另一种方法:

procedure GetImgData();
var varBuffer : OleVariant;
    tagV : TVariantArg;
    imgBuff : PByteArray;
begin
     GetMem(imgBuff, fingerPrint.ImageSize);

     try
        tagV.vt    := VT_UI1 or VT_BYREF; // 0x4011
        tagV.pbVal := Pointer(imgBuff);

        varBuffer  := OleVariant(tagV);

        if fingerPrint.getData(varBuffer) then
        begin
             // success
        end;
     finally
        FreeMem(imgBuff);
     end;
end;

getData 没有使用我发送的参数返回 true。将我的可执行文件发送给支持并告诉我 API 正在获取 0x400C(VT_VARIANT 或 VT_BYREF)而不是 0x4011。

我的代码有什么问题吗?

请帮忙!

更新:

这里来自调度接口

function GetData(var ImageData: OleVariant): WordBool; dispid 23;

来自组件包装器

..
function GetData(var ImageData : OleVariant): WordBool;
..
function TFingerPrint.GetData(var ImageData : OleVariant): WordBool;
begin
  Result := DefaultInterface.GetData(ImageData);
end;

C++ 声明

BOOL getData(const VARIANT FAR& imgData)

更新 20140313

我们的供应商发送了新的 OCX 来处理从 Delphi 收到的数据。

【问题讨论】:

  • 请您查看详细信息。我相信 C# 代码实际上是 C++。如果是这样,则函数参数不匹配。 C++ 代码按值采用 VARIANT 结构。除非函数 arg 需要引用。您的 Delphi 代码通过 var 传递 Variant。因此,请提供更多详细信息。至少包含两种语言的 getData 函数声明。
  • 当我尝试重新创建您所描述的内容时,var 类型就像0x4011 一样好。我认为您在互操作边界处的签名存在错误。所以我认为我们需要看到更多。
  • 请您添加更多详细信息,并更正编辑中的错误。我想一旦你完成了,我们就可以结束它。 FWIW,我认为将OleVariant 转换为tagVariant 是错误的。您也可以使用真正为 tagVariant 的变量并调整函数签名以匹配。
  • 如果您能告诉我更多关于互操作边界签名错误的信息,我们将不胜感激
  • 最后一条评论看起来不对。肯定有一个safecall 指定。请您停止在 cmets 中泄露详细信息。花点时间把它们放在问题中。这里有很多细节很好。这是二进制互操作。细节就是一切。

标签: c++ vb.net delphi delphi-xe


【解决方案1】:

您确定是 0x4011 而不是 0x2011?因为varArray = $2000VarArrayCreate([0,size-1],varByte) 会创建一个带有varByte 数组的OleVariant,就像VB 代码一样。如果可行,请使用VarArrayLockVarArrayUnlock 访问数据。

【讨论】:

  • 这是一个安全数组。他想要 VT_BYREF。
  • @jdc:你试过了吗?这就是VB版的幕后应该发生的事情
  • @StijnSanders 嗯。 C++ 示例代码看起来确实是假的。也许这就是问题所在。
  • @StijnSanders。是的。我尝试了它,因为这是阅读 VB Sample 后我想到的下一个解决方案。 VarArrayCreate 标志 varArray 填充 VARRAY。 API 确实需要VT_UI1 | VT_BYREF
  • VarArrayCreate 也是基于 VB 示例的最兼容的代码,不幸的是它没有工作。
猜你喜欢
  • 2015-12-01
  • 1970-01-01
  • 2010-12-18
  • 2011-02-15
  • 1970-01-01
  • 2013-11-09
  • 1970-01-01
  • 2011-03-09
  • 2016-06-26
相关资源
最近更新 更多