动态调用DLL函数有时正常,有时报Access violation的异常

typedef int (add *)(int a,int b);

void test()

{

    hInst=LoadLibraryA("aimdtl.dll");

   (FARPROC &)add=GetProcAddress(hInst,"add");

    add(1,2);

}

按这个代码执行,add函数有时OK,有时报Access violation的异常。看到提示,第一反应就是内存异常了,但是这是什么引起了内存异常呢?

于是想着用一个变量来接收add的返回值看看。

void test()

{

    hInst=LoadLibraryA("aimdtl.dll");

   (FARPROC &)add=GetProcAddress(hInst,"add");

   int sum=add(1,2);

}

结果,add函数执行了之后,还是有时OK,有时报Access violation的异常。这会是什么原因?于是谷歌了下,有人提到,可能要加__cdecall。于是我果断修改代码。新代码如下:

typedef int __cdecall (add *)(int a,int b);

void test()

{

    hInst=LoadLibraryA("aimdtl.dll");

   (FARPROC &)add=GetProcAddress(hInst,"add");

    add(1,2);

}

结果,add函数执行了之后,还是有时OK,有时报Access violation的异常。纠结了!为什么 !!这时,想起在C中调用DLL函数时,需要用__stdcall,那是不是这里也要?立即改之!

typedef int __stdcall (add *)(int a,int b);

void test()

{

    hInst=LoadLibraryA("aimdtl.dll");

   (FARPROC &)add=GetProcAddress(hInst,"add");

    add(1,2);

}

运行后,一切OK。问题至此已经解决。可这是为什么呢?于是回过头来看了看__stdcall和__cdecall的说法。

_stdcall:Win32 API的调用协议,由被调用的函数清理堆栈,所有参数自右至左入栈,生成的代码中函数名有一个_做前缀和一个@和参数的总字节数(十进制)作后缀。它不支持可变参数,但它产生的代码比_cdecl短,因为没有每次调用后的清理堆栈的代码。

_cdecl:C\C++的缺省调用协议,由调用者清理堆栈,这就是C\C++中可以使用可变参数的函数的原因,所有参数自右至作入栈,生成的代码中函数名有一个_做前缀.

至此算是明白过来了,一般dll中的函数都采用extern "C" __stdcall的方式引出函数接口的,在调用DLL中的函数时,如果没有加__stdcall和__cdecall是缺省调用了__cdecall,而__cdecall是要由调用者清理堆栈的,而在代码中并没有清理堆栈的操作,只是调用了函数,所以调

用函数的地址可能会跑飞。不跑飞就OK,而一旦跑飞就出现Access violation的异常。而_stdcall是由被调用的函数清理堆栈,所以调用函数的地址不会跑飞,自然也就OK了。

具体__stdcall/__cdecal/__fastcall的区别可以参见http://blog.csdn.net/limenglandon/article/details/8553201。

动态调用DLL函数有时正常,有时报Access violation的异常的更多相关文章

  1. C#程序实现动态调用DLL的研究(转)

    摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...

  2. 【VB技巧】VB静态调用与动态调用dll详解

    本文“[VB技巧]VB静态调用与动态调用dll详解”,来自:Nuclear'Atk 网络安全研究中心,本文地址:http://lcx.cc/?i=489,转载请注明作者及出处! [[请注意]]:在以下 ...

  3. C#程序实现动态调用DLL的研究[转]

    摘   要: 在< csdn 开发高手> 2004 年第 03 期中的<化功大法——将 DLL 嵌入 EXE >一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在 ...

  4. C#程序实现动态调用DLL的研究

    摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...

  5. 利用C#的反射机制动态调用DLL类库

    最近由于业务要求,需要动态调用DLL类库,所以研究了一下,感觉还好也不太难,今天就把自己理解的写了一个小例子(已经通过VS2005跑通),供大家一起研究和探讨,有理解不当的地方还请高手们多多指正,谢谢 ...

  6. VC动态调用DLL

    1. //函数指针声明 typedef int (_stdcall MYDLLFUN)(char* _pcOut, /*INOUT*/int *_piOutBufLen, char* _pcIn, i ...

  7. 如何动态调用 C 函数

    JSPatch 支持了动态调用 C 函数,无需在编译前桥接每个要调用的 C 函数,只需要在 JS 里调用前声明下这个函数,就可以直接调用: require('JPEngine').addExtensi ...

  8. C++利用模板在Windows上快速调用DLL函数

    更新日志 --------- 2021/08/01 更新V2.2 增加 GetHmodule 函数 - 允许用户获取HMODULE以验证加载DLL是否成功. 2021/08/03 更新V2.3 增加 ...

  9. 卸载AppDomain动态调用DLL异步线程执行失败

    应用场景 动态调用DLL中的类,执行类的方法实现业务插件功能 使用Assembly 来实现 但是会出现逻辑线程数异常的问题 使用AppDomain 实现动态调用,并卸载. 发现问题某个插件中开启异步线 ...

随机推荐

  1. PHP漏洞全解(一)-PHP网站的安全性问题

    本文主要介绍针对PHP网站常见的攻击方式,包括常见的sql注入,跨站等攻击类型.同时介绍了PHP的几个重要参数设置.后面的系列文章将站在攻击者的角度,为你揭开PHP安全问题,同时提供相应应对方案. 针 ...

  2. uva 1475 - Jungle Outpost

    半平面交,二分: 注意,题目的点是顺时针给出的: #include<cstdio> #include<algorithm> #include<cmath> #def ...

  3. java中获得jar包执行路径的方法

    当我们由于某种需要需要的得到jar的路径是可以用下面的方式来获得: basePath = new Solution().getClass().getProtectionDomain().getCode ...

  4. HDU4527+BFS

    模拟BFS搜索 对于一个将要爆炸的点,可能同时由多个点引起. /* 模拟搜索过程 */ #include<stdio.h> #include<stdlib.h> #includ ...

  5. GridView 根据要求显示指定值

    最近在写一个小项目用来练手恢复一下功力的,在Users表中有一个用户字段是状态,我使用"0"表示启用,“1”表示禁用, 存到数据库中, 由于之前有一段时间没写代码了,所以有点生疏了 ...

  6. SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-010-Introduction为类增加新方法@DeclareParents、<aop:declare-parents>

    一. 1.Introduction的作用是给类动态的增加方法 When Spring discovers a bean annotated with @Aspect , it will automat ...

  7. 执行gem install dryrun错误

    ERROR:  While executing gem ... (Gem::FilePermissionError)     You don't have write permissions for ...

  8. A9.linux驱动

    --- ---- ---

  9. 【HDOJ】Power Stations

    DLX.针对每个城市,每个城市可充电的区间构成一个plan.每个决策由N*D个时间及N个精确覆盖构成. /* 3663 */ #include <iostream> #include &l ...

  10. hdu4374One hundred layer (DP+单调队列)

    http://acm.hdu.edu.cn/showproblem.php?pid=4374 去年多校的题 今年才做 不知道这一年都干嘛去了.. DP的思路很好想 dp[i][j] = max(dp[ ...