为C6结构暴露了C#struct for VB6 app

最后更新时间: 2009-08-11美国东部时间下午2:30

几天前,我发布了一些关于一些非常奇怪的问题的问题。 好吧,我弄清楚具体是什么导致一台机器上的构建不能在其他机器上运行,甚至想出一个解决方法,但现在它给我留下了一个很好的,具体的问题:为什么?

为了重现这个问题,我创建了一个新的InteropUserControl并执行以下操作:

  1. 添加一个新的public struct MyStruct
  2. 给它一个GUID和ComVisible属性
  3. 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#在CodeProject上的模板翻译是我用来创建我的模板(项目模板,而不是项目模板)。 VB.NET版本自动生成__InteropUserControl事件接口, _InteropUserControl接口和一些相关属性。 这些是在C#版本中明确编码的,这就是两者之间的所有不同之处。

我想我找到了解决这个问题的方法。 我有同样的问题,vb6在通过传递结构调用互操作库的方法时中断。 这是我为测试DLL互操作而创建的项目,因此我在项目中拥有的只是一个表单。 但我有另一个项目(主要应用程序)与相同的参考,它工作正常。

阅读Joelpost后,我想测试他的解决方案,事实上id确实有效(使用类而不是结构)。 但是我有其他的使用结构的互操作,所以我很担心在任何时候我的应用程序可能会失败。 另外,我不想做额外的工作来创建和公开接口和一个类来替换结构。

所以,我从我的表单中获取代码并将其移动到模块中的public sub。 它立即工作。 顺便说一句,这就是我在主应用程序中实现调用的方式。

我希望它可以帮助别人。

将结构暴露给COM以便在VB6中使用是否有一些魔力?

MSDN上的文章COM Data Types *表示支持结构。 具体来说,MSDN文章说COM结构定义为:

 ByRef VALUETYPE< MyStruct > 

在页面底部还有一些关于自定义COM可调用包装器的文章,您可能希望查看这些文章。

  • 编辑(2016):原始链接已损坏,因此我将其修复为.Net Framework的3.5版。