zoukankan      html  css  js  c++  java
  • 在C++中定义接口类,在C#中实现

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

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

    简单翻译一下,

    class __declspec(dllexport) CSimpleClass { 
    public: 
      int value;
    
      CSimpleClass(int value) : value(value) 
      { 
      } 
    
      ~CSimpleClass() 
      { 
          printf("~CSimpleClass
    "); 
      }
    
      void M1() 
      { 
          printf("C++/CSimpleClass::M1()
    "); 
          V0(); 
          V1(value); 
          V2(); 
      } 
    
      virtual void V0() 
      { 
          printf("C++/CSimpleClass::V0()
    "); 
      } 
    
      virtual void V1(int x) 
      { 
          printf("C++/CSimpleClass::V1(%d)
    ", x); 
      } 
    
      virtual void V2() 
      { 
          printf("C++/CSimpleClass::V2()
    ", value); 
      } 
    }; 


          然后用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;
        } 
        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);
            }
        } 
        class CSimpleClassEx : CSimpleClass
        {
            public CSimpleClassEx(int value)
                : base(value)
            {
            }
            public override void V2()
            {
                Console.WriteLine("C#/CSimpleClassEx.V2()");
            }
        } 

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

  • 相关阅读:
    leetCode 53. maximum subarray
    leetcode strStr()
    DCNN models
    1*1 的卷积核
    leetcode 14. longest common prefix
    springMVC接受json并打开新页面
    jsp取addFlashAttribute值深入理解即springMVC发redirect传隐藏参数
    hive安装教程本地模式
    poi excel超出65536行数限制自动扩展Invalid row number (65536) outside allow
    java 构造json对象数组
  • 原文地址:https://www.cnblogs.com/wangchenggen/p/3782548.html
Copyright © 2011-2022 走看看