2012-09-24 48 views
1

我有一个用C#编写的基类,它实现了在IDL库中定义的接口。我有一个C++类来管理这个类的单个实例。我也有一个C#项目需要使用这个类[实例(通过C++项目获得)]。我想将我的基类实现的COM接口转换回我的C#基类。将COM对象转换为C#/ .NET类时遇到问题

但是,当我将从C++比例获得的通用对象转换到我的C#基类中时,我收到一个错误。当我将它投射到衍生界面时,没有问题。

下面是我的问题的类似示例。在CSDriver的NETBaseInstance函数中从不评估两个if范围。 NETBase是唯一实现COMInterface的类。所以,我知道这个值是一个NETBase,因为如果对COMInterface的范围进行评估。

public class NETBase : COMInterface{ ... } 

public class CSDriver{ 
    private NETBase m_NETBaseInstance; 

    ... 

    public object NETBaseInstance{ 
     set{ 
      COMInterface test; 
       if(value is COMInterface){ 
       // This is evaluated. 
       test = value as COMInterface; 
      } 

      if(value is NETBase){ 
       // This is not evaluated. 
       m_NETBaseInstance = value as NETBase; 
      } 

      if(test is NETBase){ 
       // This is not evaluated. 
       m_NETBaseInstance = test as NETBase; 
      } 
     } 
    } 
} 

将此COM对象成功投射到C#对象的过程是什么?难道我做错了什么?

非常感谢您提供任何答案。

回答

1

您无法直接投射。

非托管C++ API正在返回指向COMInterface接口vtable的指针;你可能会认为你知道NETBase是这个接口的唯一实现,但是.NET COM Interop基础结构没有这样的知识(事实上,严格地说你错了,因为非托管代码正在处理的COMInterface的实现是一个COM Callable Wrapper由interop基础结构创建,而不是NETBase的实例);当你从C#调用C++ API时,所有的.NET interop层可以做的就是将托管代码传递给非托管COM接口周围的Runtime Callable Wrapper,并且此RCW不是NETBase的实例,因此无法将其转换为NETBase,正如你所发现的那样。

可能有解决方法来做你想做的事情,利用你的特殊知识,任何COMInterface必须指向特定的NETBase实例。细节将取决于NETBase的性质(例如,它的状态是可序列化的)以及所有托管代码是否在同一个AppDomain中运行(例如,如果是的话,您可能能够在.NETBase类上提供静态字段和方法允许与COMInterface指向的实例会合 - 如果它真的是一个单例,就像你的问题所建议的那样)。

+0

是的,你是对的;这是一个单身人士。我曾想过在NETBase中管理单例,并按照你的建议来做同样的事情,但我的团队并不想要一个与其他人不同的类。所以,我打算自己打包NETBase(而其他类有一个包装和类本身)。谢谢你的答案。这真的很有帮助。 – swtdrgn

相关问题