基本上,当我尝试使用 VB6 调用 upnp.dll 中的函数时出现此错误,其中 upnp.dll 返回的数据类型不受 VB6 支持。以前,同样的错误发生在不同的函数/变量上,解决方法是在 oleview.exe 中打开 upnp.dll(查看类型库信息)并将所有出现的“Unsigned Long”替换为“Long”然后编译一个删除了“Unsigned”关键字的新TypeLib,这解决了那个senario的问题。
现在,我需要解决相同的问题,但需要使用不同的函数/变量,但问题是,当我在 oleview 的 upnp.dll 的 TypeLib 视图中时,我不知道需要更改或删除哪个变量数据类型。
为了完整起见,我会让你知道这个错误发生在哪里,然后我会向你展示我在修改时遇到问题的 oleview/TypeLib 视图的相关部分。(供您参考,upnp.dll 包含在 windows\system32 中,并且 oleview.exe 随 Windows SDK 工具包一起提供,如果您的计算机上还没有它)。
我正在调用函数.InvokeAction sActionName, aryIns, aryOuts
,其中 aryIns 和 aryOuts 是这样声明的变体:Dim aryIns As Variant, aryIns As Variant
- 基本上,我通常声明它,将我需要的任何输入数据放入 aryIns 中,我将获得带有 InvokeAction 调用结果的 aryOuts。好消息是,InvokeAction 将我的一般 Variant 转换为一个适当尺寸的数组,反映为我正在使用的 ActionName 返回的输出项的数量。
关于我收到错误的重点,我在“WAN 连接设备”下的“WanIPConnection”上使用(对于 sActionName)“GetStatusInfo”。我不需要为 aryIns 定义任何项目,因为此调用不需要或不需要任何输入参数,但它提供(返回)3 个项目(结果)并将它们放入 aryOuts。所以 aryOuts 最终成为一个数组,其中包含从索引 0 到 2 的项目(总共 3 个项目)......当我遍历这个 aryOuts 数组时,项目 0 和 1 被打印出来并完美地查看(没有问题)但在第 3 次item (aryOuts(2)) 我得到了上述异常。
基本上,前 2 个参数只是简单的字符串(访问这些没有问题),但 UPnP 人员将第三个参数定义为Unsigned 4 Byte Integer
(这就是问题所在),VB6 无法解释此数据类型并且不允许我访问此数组项 (aryOuts(2)),但我无法弄清楚我需要修改 TypeLib 的哪一部分,因为 InvokeAction aryOuts 的定义只是在 TypeLib 中声明为 VARIANT*,这是相关部分TypeLib 供您查看(我已经包含了我认为相关的区域,如果您想发布其他区域,请告诉我,我可以这样做):
[
odl,
uuid(A295019C-DC65-47DD-90DC-7FE918A1AB44),
helpstring("IUPnPService Interface"),
dual,
nonextensible,
oleautomation
]
interface IUPnPService : IDispatch {
[id(0x600209c5), helpstring("method QueryStateVariable")]
HRESULT QueryStateVariable(
[in] BSTR bstrVariableName,
[out, retval] VARIANT* pValue);
[id(0x600209c6), helpstring("method InvokeAction")]
HRESULT InvokeAction(
[in] BSTR bstrActionName,
[in] VARIANT vInActionArgs,
[in, out] VARIANT* pvOutActionArgs,
[out, retval] VARIANT* pvRetVal);
[id(0x600209c7), propget, helpstring("property ServiceTypeIdentifier")]
HRESULT ServiceTypeIdentifier([out, retval] BSTR* pVal);
[id(0x600209c8), helpstring("method AddStateChangeCallback")]
HRESULT AddCallback([in] IUnknown* pUnkCallback);
[id(0x600209c9), propget, helpstring("property Id")]
HRESULT Id([out, retval] BSTR* pbstrId);
[id(0x600209ca), propget, helpstring("property LastTransportStatus")]
HRESULT LastTransportStatus([out, retval] long* plValue);
};
我之前谈到的 aryOuts() 数组是由声明中的[in, out] VARIANT* pvOutActionArgs
行定义的InvokeAction
(在上面的 TypeLib 中)。基本上,整个数组被定义为一个 VARIANT* (这很好),但我无法访问pvOutActionArgs
上面定义的数组的第三个元素(索引项号 2),如何围绕这个问题修改 TypeLib?
作为参考,以及那些感兴趣的人,Hans Passant (@HansPassant) 通过要求我从 oleview.exe 暴露的 upnp.dll TypeLib 中删除 Text 的 Unsigned 部分来帮助我解决类似的情况 - 他帮助我做到了这(以及在以下帖子中生成和编译新 TypeLib (upnp.tbl) 所需的其余步骤: 标记为受限的函数或接口,或函数使用 Visual Basic 中不支持的自动化类型