将Delphi记录类型传递给VB6 DLL



VB6 DLL

我写了一个VB6 DLL,它包括以下用户定义类型(UDT),仅由基元数据类型组成。。。

Public Type MyResults
  Result1 As Double
  Result2 As Double
  Result3 As Double
  Result4 As Double
  Result5 As Double
End Type

以及以下方法。。。

Public Sub Method1(ByRef Results As Variant)
  Dim myRes As MyResults
  myRes = Results
  MsgBox "MyResults.Result1: " & myRes.Result1
  ...
End Sub

Delphi测试线束

我还用Delphi编写了一个测试工具,并创建了一个等效的Delphi记录类型来模拟VBUDT,其定义如下。。。

TMyResults = packed record
  Result1: Double;
  Result2: Double;
  Result3: Double;
  Result4: Double;
  Result5: Double;
end;

在Delphi中,我想调用VB6DLL中的Method1,并将此类型的变量作为参数传递,这样VB就可以将其解释为等效的"类型"。到目前为止,我已经尝试了以下Delphi调用。。。

procedure TMyApp.CallMethod1FromVBDLL(var MyResults: TMyResults);
var
  results: OleVariant;
  dll: Variant;
begin
  results := RecToVariant(MyResults, SizeOf(MyResults));
  dll := CreateOleObject('ApplicationName.ClassName');
  dll.Method1(results);
  ...
end;

它使用以下函数(来源:http://www.delphigroups.info/2/2c/462130.html)将记录转换为变体。。。

function TMyApp.RecToVariant(var AR; ARecSize: Integer): Variant;
var
  p: Pointer;
begin
  Result := VarArrayCreate([1, ARecSize], varByte);
  p := VarArrayLock(Result);
  try
    Move(AR, p^, ARecSize);
  finally
    VarArrayUnLock(Result); 
  end;
end;

由于DLL的Method1中myRes = Results行上的Type mismatchEOleException被报告回Delphi。

我在Delphi中准备和传递论点是否正确?我应该如何在VB6中使用参数?

如有任何协助/建议,我们将不胜感激。

问题是您的Delphi代码正在创建一个包含字节数组(Automation类型VT_UI1 or VT_ARRAY)的OleVariant,这不是VB所期望的。它需要一个UDT记录(Automation类型VT_RECORD)。

MSDN有一篇文章解释了如何在Variant中传递UDT:

通过UDT

要为后期绑定传递单个UDT或UDT的安全数组,Automation客户端必须具有将UDT的类型信息存储到VARIANT中所需的信息(如果是后期绑定,则必须对UDT进行自我描述)。VT_RECORD类型的VARIANT包装RecordInfo对象,该对象包含有关UDT的必要信息和UDT本身的指针。RecordInfo对象实现了一个新接口IRecordInfo,用于访问信息。重要的是要知道,UDT的实际存储从未归VARIANT所有;IRecordInfo指针是VARIANT唯一拥有的指针。

UDT的数据包括指向UDT描述的IRecordInfo指针pRecInfo和指向数据的指针pvRecord。

换句话说,您需要创建一个实现IRecordInfo接口并包装实际记录数据的类,然后可以使用VT_RECORD类型将该类的实例存储在OleVariant中。这将为COM和VB提供必要的元数据,以便封送和访问您的记录数据。

最新更新