将 Delphi 记录类型传递给 VB6 DLL

Passing a Delphi record type to 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 记录类型来模仿 VB UDT,其定义如下...

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

从Delphi开始,我想在VB6 DLL中调用Method1,并将这种类型的变量作为参数传递,以便VB可以将其解释为等效 "type"。到目前为止,我已经尝试了以下 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 中的参数?

任何 assistance/advice 将不胜感激。

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

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

Passing UDTs

To pass single UDTs or safearrays of UDTs for late binding, the Automation client must have the information necessary to store the type information of the UDT into a VARIANT (and if late-binding, the UDT must be self-described). A VARIANT of type VT_RECORD wraps a RecordInfo object, which contains the necessary information about the UDT and a pointer the UDT itself. The RecordInfo object implements a new interface, IRecordInfo, for access to the information. It is important to know that the actual storage of the UDT is never owned by the VARIANT; the IRecordInfo pointer is the only thing that is owned by the VARIANT.

The data for a UDT includes an IRecordInfo pointer to the description of the UDT, pRecInfo, and a pointer to the data, pvRecord.

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