在C++中定义接口类,在C#中实现

网上大部分都是C#调用C++的接口,很少有C++调用C#的,更少有在C++中定义接口类,在C#中实现。

千辛万苦,终于找到一个网址:http://www.tuicool.com/articles/AFjY7j

简单翻译一下,

在C++中定义接口类,在C#中实现
class __declspec(dllexport) CSimpleClass { 
public: 
  int value;

  CSimpleClass(int value) : value(value) 
  { 
  } 

  ~CSimpleClass() 
  { 
      printf("~CSimpleClass\n"); 
  }

  void M1() 
  { 
      printf("C++/CSimpleClass::M1()\n"); 
      V0(); 
      V1(value); 
      V2(); 
  } 

  virtual void V0() 
  { 
      printf("C++/CSimpleClass::V0()\n"); 
  } 

  virtual void V1(int x) 
  { 
      printf("C++/CSimpleClass::V1(%d)\n", x); 
  } 

  virtual void V2() 
  { 
      printf("C++/CSimpleClass::V2()\n", value); 
  } 
}; 
在C++中定义接口类,在C#中实现


      然后用dumpbin.exe等工具查看符号表,也可以直接用文本文件打开,搜关键字CSimpleClass,找到函数的符号(如果不明白,要进修一下C++编译方面的知识):

??0CSimpleClass@@QAE@ABV0@@Z    
??0CSimpleClass@@QAE@H@Z    
??1CSimpleClass@@QAE@XZ    
??4CSimpleClass@@QAEAAV0@ABV0@@Z    
??_7CSimpleClass@@6B@    
?M1@CSimpleClass@@QAEXXZ    
?V0@CSimpleClass@@UAEXXZ    
?V1@CSimpleClass@@UAEXH@Z    
?V2@CSimpleClass@@UAEXXZ

    具体是对应的函数是:

public: __thiscall CSimpleClass::CSimpleClass(int)    
public: __thiscall CSimpleClass::~CSimpleClass(void)    
public: class CSimpleClass & __thiscall CSimpleClass::operator=(class CSimpleClass const &)    
const CSimpleClass::`vftable‘    
public: void __thiscall CSimpleClass::M1(void)    
public: virtual void __thiscall CSimpleClass::V0(void)    
public: virtual void __thiscall CSimpleClass::V1(int)    
public: virtual void __thiscall CSimpleClass::V2(void)    

    接下来是在C#中,定义:

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public unsafe struct __CSimpleClass
    {
        public IntPtr* _vtable;
        public int value;
    } 
在C++中定义接口类,在C#中实现
    public unsafe class CSimpleClass : IDisposable
    {
        private __CSimpleClass* _cpp;
        private IntPtr* _oldvtbl;

        private void InitVtable(__CSimpleClass* ths, IntPtr[] arr, int len)
        {
            IntPtr* newvtable = (IntPtr*)Memory.Alloc(len * sizeof(IntPtr));
            for (int i = 0; i < len; i++)
                newvtable[i] = arr[i];
            _oldvtbl = ths->_vtable;
            ths->_vtable = newvtable;
        }

        private void ResetVtable(__CSimpleClass* ths)
        {
            IntPtr* oldvtbl = ths->_vtable;
            ths->_vtable = _oldvtbl;
            Memory.Free(oldvtbl);
        }
        // CSimpleClass constructor and destructor 
        [DllImport("cppexp.dll", EntryPoint = "??0CSimpleClass@@QAE@H@Z", CallingConvention = CallingConvention.ThisCall)]
        private static extern int _CSimpleClass_Constructor(__CSimpleClass* ths, int value);
        [DllImport("cppexp.dll", EntryPoint = "??1CSimpleClass@@QAE@XZ", CallingConvention = CallingConvention.ThisCall)]
        private static extern int _CSimpleClass_Destructor(__CSimpleClass* ths);

        // void M1(); 
        // virtual void V0(); 
        // virtual void V1(int x); 
        // virtual void V2(); 
        [DllImport("cppexp.dll", EntryPoint = "?M1@CSimpleClass@@QAEXXZ", CallingConvention = CallingConvention.ThisCall)]
        private static extern void _M1(__CSimpleClass* ths);
        [DllImport("cppexp.dll", EntryPoint = "?V0@CSimpleClass@@UAEXXZ", CallingConvention = CallingConvention.ThisCall)]
        private static extern void _V0(__CSimpleClass* ths);
        [DllImport("cppexp.dll", EntryPoint = "?V1@CSimpleClass@@UAEXH@Z", CallingConvention = CallingConvention.ThisCall)]
        private static extern void _V1(__CSimpleClass* ths, int i);
        [DllImport("cppexp.dll", EntryPoint = "?V2@CSimpleClass@@UAEXXZ", CallingConvention = CallingConvention.ThisCall)]
        private static extern void _V2(__CSimpleClass* ths);

        public delegate void V0_Delegate();
        public delegate void V1_Delegate(int i);
        public delegate void V2_Delegate();

        public V0_Delegate _v0_Delegate;
        public V1_Delegate _v1_Delegate;
        public V2_Delegate _v2_Delegate;

        public CSimpleClass(int value)
        {
            //Allocate storage for object 
            _cpp = (__CSimpleClass*)Memory.Alloc(sizeof(__CSimpleClass));
            //Call constructor 
            _CSimpleClass_Constructor(_cpp, value);
            //Create delegates for the virtual functions 
            _v0_Delegate = new V0_Delegate(V0);
            _v1_Delegate = new V1_Delegate(V1);
            _v2_Delegate = new V2_Delegate(V2);
            IntPtr[] arr = new IntPtr[3];
            arr[0] = Marshal.GetFunctionPointerForDelegate(_v0_Delegate);
            arr[1] = Marshal.GetFunctionPointerForDelegate(_v1_Delegate);
            arr[2] = Marshal.GetFunctionPointerForDelegate(_v2_Delegate);
            //Create a new vtable and replace it in the object 
            InitVtable(_cpp, arr, 3);
        }
        public void Dispose()
        {
            //reset old vtable pointer 
            ResetVtable(_cpp);
            //call destructor 
            _CSimpleClass_Destructor(_cpp);
            //release memory 
            Memory.Free(_cpp);
            _cpp = null;
        }
        public void M1()
        {
            _M1(_cpp);
        }
        public virtual void V0()
        {
            _V0(_cpp);
        }
        public virtual void V1(int i)
        {
            _V1(_cpp, i);
        }
        public virtual void V2()
        {
            _V2(_cpp);
        }
    } 
在C++中定义接口类,在C#中实现

 

在C++中定义接口类,在C#中实现
    class CSimpleClassEx : CSimpleClass
    {
        public CSimpleClassEx(int value)
            : base(value)
        {
        }
        public override void V2()
        {
            Console.WriteLine("C#/CSimpleClassEx.V2()");
        }
    } 
在C++中定义接口类,在C#中实现

     这样就可以试验一下了。如果是在C++中回调C#的集成类,实际上对应的C++中CSimpleClass对象的是:private __CSimpleClass* _cpp;

 

 

 

 

在C++中定义接口类,在C#中实现,布布扣,bubuko.com

在C++中定义接口类,在C#中实现

上一篇:【转】Tomcat出现SEVERE: IOException while loading persisted sessions: java.io.EOFException java.io.EOFException问题的解决方案


下一篇:入门级的Java Socket代码