我可以在非托管代码中实现托管的COM可见接口吗?

时间:2015-05-18 13:53:04

标签: c# com-interop

我有一个用C#实现的类,我希望从本机应用程序中使用它。 C#类具有由接口描述的依赖关系,该关系由实例化该类的代码传递。我想在本机应用程序中实现此接口,并通过COM将其传递给C#对象。非常简化,C#代码如下所示:

[ComVisible(true)]
[Guid("910E8445-7A62-403F-BAEE-17AB0C169CA8")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IComWidget
{
   void SetClient(IComWidgetClient client);
   void DoStuff();
}

[ComVisible(true)]
[Guid("850F3EBB-CD18-4E16-881F-50B50DD5AEB0")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IComWidgetClient
{
  int GetValue();
}

[ComVisible(true)]
[Guid("86B9EC33-6CDF-438F-9A67-57D009723027")]
[ClassInterface(ClassInterfaceType.None)]
public class ComWidget : IComWidget
{
   private IComWidgetClient m_Client;

   public void DoStuff()
   {
      var i = m_Client.GetValue();
      Debug.WriteLine("value was {0}", i);
   }

   public void SetClient(IComWidgetClient client)
   {
      m_Client = client;
   }
}

本机应用程序将COM库作为具有适当清单的并排程序集加载,并实现IComWidgetClient接口。它似乎可以工作,但是当在系统上运行自动化测试时,一些测试因未处理的ExecutionEngineExecption而失败。它失败的方式(测试过程中止)闻起来像垃圾收集过程中的某种腐败。 我想我可以编写一个托管c ++单元测试,模拟导致错误的步骤。至少它以同样的方式失败。测试看起来像这样:

[TestMethod]
void TestStuff()
{
   IComWidgetPtr sut = NULL;
   NativeClient* client = NULL;

   try
   {
      sut = IComWidgetPtr(__uuidof(ComWidget));
      client = new NativeClient();

      IComWidgetClient* pvObject;
      client->QueryInterface(IID_IComWidgetClient, (void**)&pvObject);

      sut->SetClient(pvObject);

      sut->Release();

      GC::Collect();
      GC::WaitForPendingFinalizers();

      Assert::IsTrue(true); // If we get this far, everything went OK...
   }
   finally
   {
      sut = NULL;
      delete client;
      client = NULL;
   }
};

其中NativeClient是实现IComWidgetClient的简单本机对象

public class NativeClient: IComWidgetClient
{
   ...
}

出了什么问题?我想尽力做什么?

完整的源代码可以在这里找到: https://drive.google.com/file/d/0B-D57qCpESa5MnpZUXZRN2pyNnc/view?usp=sharing

0 个答案:

没有答案