VC6.0 The value of ESP was not properly saved across a function call 错误的解决方法
首先在.dll里面简单写了一个int返回值的函数
extern "C" DLL_1_API int fTest_1(int k)
{
int i=5;
int j=6;
i=i+k;
return i*j;
}
然后在.exe文件里面调用dll文件
int main()
{
int a;
int b=3;
HINSTANCE dll123;
typedef int (WINAPI *myfun)(int);
dll123=LoadLibrary("DLL_1.dll");
if(dll123==NULL)
{
printf("cannot find dll");
}
myfun msg1; //FARPROC 4字节指针
msg1=(myfun)GetProcAddress(dll123,"fTest_1");
if (msg1==NULL)
{
printf("cannot find function");
}
else
{
a=msg1(b);
printf("%d\n",a);
}
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方式。
所以这个问题出现的原因是typedef int (WINAPI* myfun)(int);这句代码需要去掉前面的WINAPI* 因为我是win32 dll 如果不是win32 dll的话再充实使用WINAPI*这个函数
具体的组合方式太多了,反正知道错误的原因是声明相应的函数未匹配就行了。
修改代码之后运行程序发现已经可以得到正确结果。