Trouble Casting COM Object to a C#/.NET Class

落爺英雄遲暮 提交于 2019-12-24 14:44:13

问题


I have a base class that is written in C# that implements an interface defined in an IDL library. I have a C++ class that manages the single instance of this class. I also have a C# project that needs to make use of this class [instance (that is obtained through the C++ project)]. I want to cast the COM interface that my base class implements back into my C# base class.

However, when I cast the generic object that I acquired from the C++ proportion into my C# base class, I received an error. When I cast it to the derived interface, there is no problem.

Below is the similar example of my problem. The two if scopes are never evaluated in the NETBaseInstance function of CSDriver. The NETBase is the only class that implements COMInterface. So, I know for sure that the value is a NETBase since the if scope for COMInterface is evaluated.

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;
            }
        }
    }
}

What is the process to cast this COM object to the C# object successfully? Am I doing something wrong?

Thank you in advance for any answers.


回答1:


There is no way you can cast it directly.

The unmanaged C++ API is returning a pointer to the COMInterface interface vtable; you might think you know that NETBase is the only implementation of this interface, but the .NET COM Interop infrastructure has no such knowledge (indeed, strictly speaking you are wrong, because the implementation of COMInterface which the unmanaged code is dealing with is a COM Callable Wrapper created by the interop infrastructure, not an instance of NETBase); when you call the C++ API from C#, all the .NET interop layer can do is pass your managed code a Runtime Callable Wrapper around the unmanaged COM interface, and this RCW is not an instance of NETBase, so you cannot cast it to NETBase, as you have found.

There may be workarounds to do what you want, making use of your special knowledge that any COMInterface must point to a specific NETBase instance. The details will depend on the nature of NETBase (e.g. is its state serializable) and on whether or not all the managed code runs in the same AppDomain (e.g. if yes, you may be able to provide static fields and methods on the NETBase class to allow rendezvous with the instance the COMInterface points to - trivial if it really is a singleton as your question suggests).



来源:https://stackoverflow.com/questions/12557544/trouble-casting-com-object-to-a-c-net-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!