首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >运行时错误458,变量使用Visual中不支持的自动化类型

运行时错误458,变量使用Visual中不支持的自动化类型
EN

Stack Overflow用户
提问于 2012-08-31 05:42:08
回答 1查看 11.4K关注 0票数 4

基本上,当我试图使用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的相关部分(我已经包括了我理解的相关区域,如果您想发布其他区域的话),让我知道,我可以做到这一点:

代码语言:javascript
复制
[
  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中不支持的自动化类型 ),以供参考。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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变体。

修改变量的变体类型可能非常危险,除非您知道自己在做什么。在这种情况下,您可以很安全地将无符号类型转换为它们的签名对应类型,而不会泄漏内存或任何其他副作用。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12209510

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档