标记为COM互操作的C#DLL如何在vb6应用程序中工作

Dav*_*vid 0 .net c# vb6

我有一个简单的C#库,已为COM互操作注册。我已经在vb6应用中添加了对此的参考。我运行了vb应用程序,一切正常。我想知道这是如何工作的。我检查了mamager任务,并在进程中看到VB6.exe,但看不到任何与.net相关的信息。

代码:vb6

Dim a As CsharpdllForVBHack.ComAdder
Private Sub Command1_Click()
    Set a = New CsharpdllForVBHack.ComAdder
    a.Add 1, 4
End Sub
Run Code Online (Sandbox Code Playgroud)

代码:C#.net

 [ComVisible(true)]
 public class ComAdder
 {
    [ComVisible(true)]
    public void add (int a,int b)
    {
        TestForm testForm = new TestForm(a+b);
        testForm.ShowDialog();
    }
 }
Run Code Online (Sandbox Code Playgroud)

我也想知道完成后如何处理该com对象

我们注意到,每次单击按钮并关闭表格时,即使添加set a = Nothing,使用的内存也会增加几百kb

Mar*_*haw 5

在您的情况下,VB实例化一个驻留在.NET程序集中的COM可调用包装器类(CCW)。通常的COM类型的事情在这里发生。首先,COM在注册表中查找类的GUID,并找到程序集DLL,然后将其加载到VB组件的过程中。COM试图找到一个函数,该函数检索指向标准COM接口的指针,您可以使用该接口实例化COM类。您现在有了一个COM对象。

但这还不是全部。实例化CCW时,它还确保加载.NET运行时,然后创建.NET类的实例。您的COM对象具有一个基于.NET接口的接口。CCW本质上将所有调用从COM接口转发到.NET接口,将COM数据类型转换为.NET数据类型,如果有返回值和out参数,则再次返回。

至于第二点-在这种情况下,请不要打扰。当VB到达过程的末尾(或Exit Sub,或引发错误)时,它跳到一个子例程,该子例程清除所有过程级变量。如果清除了对象变量,则对COM对象的引用计数将减少。如果引用计数为零,则COM实例将自行终止。

在您的情况下,当COM类自行终止时,它会采取极端措施来确保.NET对象被销毁,但您不能像所有.NET对象一样依赖此行为。