基本上,当我试图使用upnp.dll调用VB6中的一个函数时,就会出现这个错误,upnp.dll将返回VB6不支持的数据类型。在此之前,同样的错误发生在不同的函数/变量上,解决方案是在upnp.dll中打开oleview.exe (查看类型库信息),将所有出现的“无符号长”替换为"Long“,然后用删除的”无符号“关键字编译一个新的TypeLib,从而解决了该文档的问题。
现在,我需要解决相同的问题,但对于一个不同的函数/变量,但问题是,当我处于oleview的TypeLib视图upnp.dll中时,我不知道需要更改或删除哪些变量数据类型。
为了完整起见,我会让您知道这个错误发生在哪里,然后我将向您展示oleview/TypeLib视图的相关部分,说明我在修改时遇到了问题。(关于您的信息,upnp.dll包含在windows\system32 32中,如果您的计算机上还没有Windows,则附带oleview.exe )。
我调用函数.InvokeAction sActionName, aryIns, aryOuts,其中aryIns和aryOuts是像这样声明的变体:Dim aryIns As Variant, aryIns As Variant -基本上,我通常声明它,将我需要的任何输入数据放入aryIns中,然后我将得到aryOuts和InvokeAction调用的结果。好的是,InvokeAction将我的一般变体转换成一个适当尺寸的数组,以反映我正在使用的ActionName返回的输出项的数量。
这就是我得到错误的关键所在,我在“广域网连接设备”下的“sActionName”上使用了(GetStatusInfo) "WanIPConnection“。我不需要为aryIns定义任何项,因为这个调用不需要或不需要任何输入参数,但是它提供了(返回)3个项(结果),并将它们放在aryOuts中。因此,aryOuts作为一个数组结束,其项从索引0到2 (3项总计).当我循环这个aryOuts数组时,项目0和1将被打印出来,并被完美地查看(没有问题),但是在第三项(aryOuts(2))上,我得到了上面的异常。
基本上,前两个参数只是简单的字符串(访问这些字符串没有问题),但是第三个参数由UPnP people定义为一个Unsigned 4 Byte Integer (这就是问题所在),VB6无法解释这个数据类型,也不允许我访问这个数组项( aryOuts (2)),而且我也不知道我需要修改的TypeLib的哪一部分,因为InvokeAction aryOuts的定义只是作为一个变体*在TypeLib中描述的,这里是您的视图的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);
};我之前提到的[in, out] VARIANT* pvOutActionArgs ()数组是由InvokeAction声明中的aryOuts行(在上面的TypeLib中)定义的。基本上,整个数组被定义为一个变体*(这很好),但是我在访问上面定义的pvOutActionArgs数组的第三个元素(索引项2)时遇到了问题,如何修改这个问题的TypeLib呢?
汉斯·帕桑特(@HansPassant)帮助我解决了类似的情况,要求我从upnp.dll TypeLib中删除oleview.exe公开的文本中未签名的部分--他帮助我完成了这一工作(以及生成和编译新的TypeLib (upnp.tbl)所需的其余步骤:标记为受限的函数或接口,或者该函数使用Visual中不支持的自动化类型 ),以供参考。
发布于 2012-08-31 08:52:04
尝试将aryOuts(2)分配给Long变量(lStatusBits = aryOuts(2))。加入VT_UI4变体在VB6中应该是没有问题的,除非它被For Each vElem ...循环阻塞(vElem是变体)或变体赋值。在您的类型列表中,没有什么可以解决这种行为。如果没有其他工作,您可以使用类似于Call CopyMemory(aryOuts(2), VT_I4, 2)的VT_I4 =3这样的东西手动更改变体类型
COM变体是一种数据结构,它以一个名为vartype的int16成员开始,它定义了存储在变量中的数据的类型(在您的例子中是aryOuts(2))。
VarType VT_UI4用于无符号int32值。VB6 Longs被转换为有符号的VT_I4 = 3变体。
VarType VT_UI2用于无符号int16值。VB6 Integers被转换为有符号的VT_I2 = 2变体。
修改变量的变体类型可能非常危险,除非您知道自己在做什么。在这种情况下,您可以很安全地将无符号类型转换为它们的签名对应类型,而不会泄漏内存或任何其他副作用。
https://stackoverflow.com/questions/12209510
复制相似问题