上次更新: 2009-08-11美国东部时间下午2:30
几天前,我发布了this question关于一些非常奇怪的问题。好吧,我弄清楚具体是什么导致一台机器上的构建不能在其他机器上运行甚至出现了解决方法,但现在它给我留下了一个很好的,具体的问题:为什么?
要重现此问题,我创建一个新的InteropUserControl并执行以下操作:
public struct MyStruct
:ComVisible
属性GetMyStruct
成员添加到_InteropUserControl
界面,并在InteropUserControl
中实施。 MyStruct
:
[Guid("49E803EC-BED9-4a08-B42B-E0499864A169")]
[ComVisible(true)]
public struct MyStruct {
public int mynumber;
}
_InteropUserControl.GetMyStruct()
:
[DispId(7)]
void getMyStruct( int num, ref MyStruct data );
(我已尝试返回MyStruct
而不是通过引用传递。)
InteropUserControl.GetMyStruct()
实施:
public void getMyStruct( int num, ref MyStruct data ) {
data = new MyStruct();
data.mynumber = num * 2;
}
我也签署程序集并将其安装到GAC并注册Regasm。将它添加到新的VB6项目并添加对GetMyStruct()
的调用并在我们的构建机器上进行编译后,它拒绝在其他机器上运行。
为了解决这个问题,我不得不将一个类暴露给COM而不是结构,并且基本上将GetMyStruct
更改为:
public void GetMyData( int num, MyClass data ) {
data.mynumber = num * 2;
}
在我的实际项目中,我在内部检索结构,然后将结构中的所有字段值复制到客户端传递给方法的类实例上的匹配成员。
那么为什么一个结构导致了这种行为并且一个类运行良好?将结构暴露给COM以便在VB6中使用是否有一些魔力?
我认为它可能与OLE自动化有关。
注意:我也尝试返回结构而不是使用ref
参数,但这并没有改变行为。
编辑以添加指向项目模板的链接:
Interop Forms Toolkit 2.0是最初的VB.NET项目模板和dll。我没有引用dll,所以你可能不需要安装它。
C# Translations of templates on CodeProject是我用来创建我的(项目模板,而不是项目模板)。 VB.NET版本自动生成__InteropUserControl
事件接口,_InteropUserControl
接口和一些相关属性。这些是在C#版本中明确编码的,这就是两者之间的所有不同之处。
答案 0 :(得分:2)
我想我找到了解决这个问题的方法。 我有同样的问题,vb6在通过传递结构调用互操作库的方法时中断。这是我为测试DLL互操作而创建的项目,因此我在项目中拥有的只是一个表单。但我有另一个项目(主要应用程序)具有相同的参考,它工作正常。
在阅读Joel帖子之后,我想测试他的解决方案,事实上id确实有效(使用类而不是结构)。但我还有其他使用结构的互操作,所以我很担心在任何时候我的应用程序都可能失败。另外,我不想做创建和公开接口的额外工作以及替换结构的类。
所以,我从表单中获取代码并将其移动到模块中的public sub。它立即工作。顺便说一下,这就是我在主应用程序中实现调用的方式,该工作正常。
我希望它可以帮助别人。
答案 1 :(得分:1)
暴露一个是否有一些魔力 struct to COM在VB6中使用?
MSDN上的文章COM Data Types *表示支持结构 。具体来说,MSDN文章说COM结构定义为:
ByRef VALUETYPE< MyStruct >
在页面底部还有一些关于自定义COM可调用包装器的文章,您可能希望查看这些文章。