动态调用dll遇到的问题

问题:动态调用第三方提供的dll报错。

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

调用源码:

typedef bool (WINAPI *SEALPARSE)(unsigned char*, int, char*);
static int ConvertAsnToXml(unsigned char* asnBuffer, int bufferLen, char** xmlData)
{
	HINSTANCE hDllInst = LoadLibrary("DllSESealParse.dll");
	if(hDllInst == NULL){
		::MessageBox(NULL,"DllSESealParse.dll加载失败!","错误",IDOK);
		return -1;
	}else{
		SEALPARSE asnToXml = NULL;
		asnToXml = (SEALPARSE)GetProcAddress(hDllInst, "SESealParse_SESealDataASNToXml");

		if(asnToXml)
		{
			*xmlData = (char*)malloc(40*1024);
			bool bRet = asnToXml(asnBuffer, bufferLen, *xmlData);
		}
		FreeLibrary(hDllInst);
	}
	return 0;
}

  

错误原因:

定义函数指针原型时出错。

其实定义的没有错,但是编译器不认识而已,因为调用的dll函数是一个远函数,而且是一个C函数,必须告诉编译器它是个c函数才行。那么就可以在定义该函数的时候加上一句话,

FAR PASCAL 或者 __stdcall 这个就OK了。

具体做法:

比如说你要定义一个 返回类型为空,参数为空的函数指针:

typedef void (*LPFUN)(void);

这样确实跟我们dll里的函数匹配了,上面也说了,我们应该添上几个字,告诉编译器这个是一个远的C函数。

typedef void (WINAPI *LPFUN)(void);

typedef void (__stdcall *LPFUN)(void);

typedef void    (FAR PASCAL *LPFUN)    (void);

像上面这样定义就OK了,如果用的是VC++,那么直接用第一种定义就ok了。

注意,上面是使用 MFC (DLL)的做法。

如果是WIN32 DLL,得相应的去掉WINAPI ,__stdcall ,FAR PASCAL 这几个参数。因为WIN32 DLL 默认的入栈方式为 __cedcall方式,不是__stdcall方式。

具体的组合方式太多了,反正知道错误的原因是声明相应的函数未匹配就行了。实在不行,一个一个的试吧

解决方法:

查看:Project->Properties->Configuration Properties->C/C++->advanced->calling Convention  为  __cdecl

将代码中的

typedef bool (WINAPI *SEALPARSE)(unsigned char*, int, char*);

修改为typedef bool (__cdecl *SEALPARSE)(unsigned char*, int, char*);
时间: 2024-09-29 02:14:02

动态调用dll遇到的问题的相关文章

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

动态调用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的异常.看到提示,第一反应就是内存异常

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

摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资源中释放出来,通过静态加载延迟实现DLL函数的动态加载,程序退出后实现临时文件的自动删除,从而为解决“DLL Hell”提供了一种解决方案.这是一个很好的设计思想,而且该作者也用C++实现了,在Internet上也有相似的VB程序,但在某一技术论坛上提起这种设计方法时,有网友提出:“这种方法好是好,但就是启动

MFC动态调用dll到指定的进程中(win7系统vs2013环境下)

一.主程序 1.新建一个MFC项目,类型选择基于对话框 2.写一个简单的窗体 点击启动事件 MessageBox(L"调用Dll到程序中成功."); 二.要调用的Dll 1.新建一个win32dll 选择dll.勾选导出符号 1.生成Dll项目 此时会在主程序Main的debug文件夹中生成了Dll.dll和Dll.lib文件 三.配置主程序Main的属性 1.选择链接器--输入--附加依赖项:Dll.lib 1.选择连接器--输入--常规--附加库目录:..\Debug 1.包含头文

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

原文:C#程序实现动态调用DLL的研究 摘  要:在<csdn开发高手>2004年第03期中的<化功大法--将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资源中释放出来,通过静态加载延迟实现DLL函数的动态加载,程序退出后实现临时文件的自动删除,从而为解决"DLL Hell"提供了一种解决方案.这是一个很好的设计思想,而且该作者也用C++实现了,在Internet上也有相似的VB程序,但在某一技术论坛

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

摘   要: 在< csdn 开发高手> 2004 年第 03 期中的<化功大法——将 DLL 嵌入 EXE >一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资源中释放出来,通过静态加载延迟实现DLL函数的动态加载,程序退出后实现临时文件的自动删除,从而为解决“ DLL Hell ”提供了一种解决方案.这是一个很好的设计思想,而且该作者也用 C++ 实现了,在 Internet 上也有相似的 VB 程序,但在某一技术论坛上提起这种设计方法时

C# 动态调用DLL库

最近经常用到C#动态调用类库,简单的做下记录方便以后查询. 使用下面的几行代码就可以简单实现DLL类库的调用了 1 using System.Reflection; // 引入该命名空间 2 3 // 获取rocky.dll的文件路径 4 Assembly ass = Assembly.LoadFrom("./_lib/rocky.dll"); 5 // 获取该dll中命名空间RockyNameSpace中Study类 6 Type type = ass.GetType("R

C#利用反射动态调用DLL并返回结果,和获取程序集的信息

反射的基本概念: .Net Framework 中提供了反射机制,可以再加载程序运行时,动态获取和加载程序集,并且可以获取到程序集的信息 创建Assembly和Entity两个程序集,在Assembly中添加Entity引用,如下图: namespace Entity { public class GetData { public static SIMPEntities SIMP = new SIMPEntities(); /// <summary> /// 查询方法--返回序列化json /

动态调用dll

LoadLibrary的头文件是#include <Windows.h> 假设要调用dll中的函数原型是 int func(int a,char *); HMODULE dll; dll = LoadLibrary("dll的路径名"); int (*func)(int,char *); func = (int(*)(int,char *))GetProcAddress(dll,"func");

C# 通过反射类动态调用DLL方法

网上看了很多关于反射的思路和方法,发现这个还算不错 //使用反射方: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { //声明一个反射类对象 Assembly a