如何将数组从 COM 传递回 Visual Basic?

Spa*_*ott 4 arrays vb6 com

这应该很简单。但我没有找到解决方案。也许是因为它太老了(VB和COM)

我试图将一个小整数数组(或者甚至只是字节,就像我在这个问题的示例中尝试过的那样)返回一个 COM 注册的进程内 DLL,使用 ATL 用 C 编写,到 VB6 应用程序。

我确实找到了很多关于走另一条路的信息。

据我了解,VARIANT 是解决方案,因为只需将一个基于 C 的数组传递回 VB 应用程序就必须进行编组,并且需要知道其大小。

我的优势在于我正在开发 COM 对象,并针对 VB 应用程序对其进行测试。虽然我的VB技能几乎为零。

许多其他调用按预期工作,将数据发送到 COM DLL,并从 COM DLL 中获取整数或 BSTR,并在 VB 中使用它们。但是,这个原始值数组不起作用。

首先我以为我没有正确编码VB,因为我对VB知之甚少。然后我想一定是C代码没有正确创建VARIANT数组。现在我不知道该怎么想。

我的结果是 VB 中的调用返回,并且 VB Watch 窗口显示 VARIANT 但没有内容(字面意思是空白,没有描述为“空”或“空”或任何内容)。(为什么 VB 坚持将变量的第一个字母大写,谁也说不准……)

在此输入图像描述

当我尝试从 VARINAT 访问索引时,它因索引越界而失败。

我尝试“ReDim”它,并得到更多变体,都说“空”。但至少他们确实告诉我“空”。

因此,从 DLL 返回的 VARIANT 中似乎没有任何内容。

我已经从 OLE 标头尝试了几个 VT_,要么得到空的 VARIANT,要么得到“不支持自动化类型”的错误。

COM 服务器中的 C++ 代码如下(已清理以供发布)。我尝试过 VT_UI1、VT_UI4、VT_INT 和其他几种类型:

STDMETHODIMP CClass::getArrayData(VARIANT* pVal, long *result) {
    unsigned char arry[4];
    unsigned long count;
    unsigned char *pData;
    arry[0] = 5; arry[1] = 6; arry[2] = 7; arry[3] = 8;     //  Just throw some data in
    count = 4;
    *result = count;

    pVal->vt = VT_ARRAY |VT_UI1;                            //   A VT of type unsigned bytes+array
    pVal->parray = SafeArrayCreateVector(VT_UI1,0,count);   //  Create 4 elements
    SafeArrayAccessData(pVal->parray, (void**) &pData);     //  Lock the memory for access
    memcpy(pData, arry, count * sizeof(unsigned char));     //  Copy the bytes in
    SafeArrayUnaccessData(pVal->parray);                    //  Release it
    return S_OK;                                            //  And we're happy...
}
Run Code Online (Sandbox Code Playgroud)

其 IDL 条目是

[id(13), helpstring("method getArrayData")] HRESULT getArrayData([out] VARIANT* pVal, [out, retval] long * result);
Run Code Online (Sandbox Code Playgroud)

VB代码是:

Private Sub getdata_Click()
    Dim result As Integer
    Dim data() As Variant
    Dim value As Integer
    Dim strvalue As String

    result = mInterface.getArrayData(data)
    value = data(1)
    strvalue = CStr(value)
    ListBox.AddItem (" " + strvalue)
End Sub
Run Code Online (Sandbox Code Playgroud)

VB 应用程序确实得到了 4 的返回值,所以我知道大部分都在工作。但数组里什么也没有。

我没主意了。这里的目标是向 VB 返回一个非常小的值数组,以便 VB 应用程序可以使用索引访问它们:data(0)、data(1)、data(2) ....

我真的不想编写十几个左右的函数来一次将值拉回一个。

任何帮助TIA。

斯科蒂

Sim*_*ier 5

你离解决方案已经不远了。根据您的getArrayData定义,您可以简单地从 VB 中这样调用它:

Dim b As Variant
Dim result As Integer
result = mInterface.getArrayData(b)
Run Code Online (Sandbox Code Playgroud)

但是,您也可以将其定义为 .idl 中的属性,如下所示:

[id(2), propget] // note propget
HRESULT ArrayData([out, retval] VARIANT* pVal);
Run Code Online (Sandbox Code Playgroud)

在 C/C++ 中就像这样(你不需要结果,因为数组是自描述的):

HRESULT STDMETHODCALLTYPE get_ArrayData(VARIANT* pVal) ...
Run Code Online (Sandbox Code Playgroud)

在 VB 中就像这样:

Dim a As Variant
a = mInterface.ArrayData
Run Code Online (Sandbox Code Playgroud)

以下是 a 和 b 变体的 VB 监视:

在此输入图像描述

PS:VB(6) 很旧,但 COM 不是,它仍然在 Windows 中随处使用:-)