网上大部分都是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\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);
}
};
然后用dumpbin.exe等工具查看符号表,也可以直接用文本文件打开,搜关键字CSimpleClass,找到函数的符号(如果不明白,要进修一下C++编译方面的知识):
[email protected]@[email protected]@@Z
[email protected]@[email protected]@Z
[email protected]@[email protected]
[email protected]@[email protected]@@Z
[email protected]@[email protected]
[email protected]@@QAEXXZ
[email protected]@@UAEXXZ
[email protected]@@[email protected]
[email protected]@@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 = "[email protected]@[email protected]@Z", CallingConvention = CallingConvention.ThisCall)]
private static extern int _CSimpleClass_Constructor(__CSimpleClass* ths, int value);
[DllImport("cppexp.dll", EntryPoint = "[email protected]@[email protected]", 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 = "[email protected]@@QAEXXZ", CallingConvention = CallingConvention.ThisCall)]
private static extern void _M1(__CSimpleClass* ths);
[DllImport("cppexp.dll", EntryPoint = "[email protected]@@UAEXXZ", CallingConvention = CallingConvention.ThisCall)]
private static extern void _V0(__CSimpleClass* ths);
[DllImport("cppexp.dll", EntryPoint = "[email protected]@@[email protected]", CallingConvention = CallingConvention.ThisCall)]
private static extern void _V1(__CSimpleClass* ths, int i);
[DllImport("cppexp.dll", EntryPoint = "[email protected]@@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;
在C++中定义接口类,在C#中实现,布布扣,bubuko.com