文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>高级话题:P/Invoke调用dll函数,将本来void的函数声明为带返回值的,在win7出错,在winxp下正常,理由是?

高级话题:P/Invoke调用dll函数,将本来void的函数声明为带返回值的,在win7出错,在winxp下正常,理由是?

时间:2010-10-13  来源:不及格的程序员-八神

作者:不及格的程序员

情况描述:

我在win32 dll 项目中封装了段asm代码调用另一个dll中的函数. 在我的win32 dll项目中公开的函数声明如下:

 1 extern "C" _declspec(dllexport) void No(const char* source, char* result)
 2 {    
 3     _asm
 4     {            
 5         mov eax, source
 6         push eax
 7         mov eax, result
 8         push eax
 9         call pFun //pFun 是我从另一个dll中用GetProcAddress函数提取的函数地址,这个函数规则是被调用者清除栈;
10         //下面使用eax寄存器,向调用者返回结果,而实际上我们的函数声明并没有返值,这种调用在我的winxp上调用是成功的.
11         //但是在另一台win7系统中,当这此函数返回时却总是失败,报异常.
12         //由于我的最终项目是wcf项目托管于iis7下,当发生异常时,提示ntdll堆被破坏.....
13         mov         eax,dword ptr [result]  
14         add         eax,1  
15         mov         dword ptr [result],eax        
16     }
17 }
  

下面是我在C#项目中声明的函数导入代码;  

[DllImport("No.dll", CallingConvention = CallingConvention.Cdecl)]

private static extern void No(string strArg0, byte[] strArg1); //此种调用方式,在winxp,win7系统都可以正常运行,结果是通过strArg1传递的.


//注意:下面代码声明了string类型的返回值,也就是获取eax返回的地址.  

private static extern string No(string strArg0, byte[] strArg1);


此种调用方式不能在win7系统下运行,但也是仅仅是第一次报异常,当第二次调用此函数时,就可以通过返回值取到结果.

我的问题是为什么这种方式会报异常呢?

难道win7下CLR jit编译做了更严格的内存检查吗?

或者与JIT没有关系,而是由于系统api的低层函数有更多的检查呢?

我目前还没有找到这个问题所在,但我非常有兴趣....想知道原因,与大家共同讨论一次吧.   

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载