这应该很简单。但我没有找到解决方案。也许是因为它太老了(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。
斯科蒂
你离解决方案已经不远了。根据您的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 中随处使用:-)
| 归档时间: |
|
| 查看次数: |
80 次 |
| 最近记录: |