C++和C#之间互相调用经验详谈(三)

2014-02-08 13:37:06 · 作者: · 浏览: 471

 

  看看在C#中时如何使用的把。当然这一部分的内敛、委托、开辟内存、托管到非托管转换时少不了的,老规矩,看代码把。

  先定义委托和内敛。

  //委托 参数分别为 this指针 成员函数地址 参数

  delegate void testcall(int pthis, int pfun, int param);

  byte[] codetest = {

  // 0xCC,

  0x8B, 0x5C, 0x24, 0x0C, //mov ebx,[esp+0Ch] 第三个参数 @@

  0x8B, 0x44, 0x24, 0x08, //mov eax,[esp+08h] 函数地址

  0x8B, 0x4C, 0x24, 0x04, //mov ecx,[esp+04h] this 指针

  0x53, //push ebx 参数入栈 @@

  0xFF, 0xD0, //call eax

  0xC3 // ret

  };

  书写内敛汇编当然可以考研我们的功底啦,看看你知道不知道底层是如何实现的、如何入栈、出栈、传值、传指针、传引用、堆栈平衡等。还有一点,书写汇编虽容易,但是机器指令我们并不都知道,山人自有妙计,汇编代码贴到VC中,ALT+8看反汇编,在拷贝回来即可。

  以上代码中,完成接口第三个函数调用,带有一个整形参数,并且传值。

  注释掉@@部分完成接口第二个函数调用,无参数。

  为了简便都写在一个里面,实际运用中,你可以按照不同格式分开。

  接下来看看如何调用,主要代码如下。

  VirtualAlloc……之前肯定得先开辟内存啊

  Marshal.Copy(codetest, 0, handle, codetest.Length);

  testcall Customer = Marshal.GetDelegateForFunctionPointer(handle, typeof(testcall)) as testcall;

  int bb = 22;

  Customer (fun[0], fun , bb);

  不错,这就是子模块调用父相关逻辑的主要实现。

  3. 后话

  这就是相互调用的所有部分吗?这次答案是否定,实际上远远不至于此,我们此次实现的,只是最最基本的部分,尤其在参数上,我们用的最简单的类型 int,实际使用中,对于两者之间都存在的基本类型,还好说一点,当涉及到字符串、数组、结构体等这些类型时,真的会让你很麻烦的,尤其是字符串,两边还不一样……

  其中对参数类型来说,我们用的是传值方式,直接将值push,对于引用或者指针要把其地址push,就可以实现了,当然还是针对最基本的类型来说的。

  对于字符串参数的,我用全局函数实现了一个接口(具体的可以看代码),这样其中大部分转换操作,对我们就透明了,为何不自己搞?我有时间在补充进去把,这些就留给你们了,同样你们搞出来之后要告诉我啊,这里给大家一个建议,处理字符串时,在C#中最好使用char数组,但在书写内敛汇编时要注意,数组前面可有数组的大小,要偏移过去。

  …

  …

  等把这一切都搞定之后,动态创建、嵌入VB的、C#的、WPF的以及她3D部分、硬件加速部分……

  不错,如此看来,现在才刚刚开始……

  希望能给大家起到一个抛砖引玉作用。