调用动态链接库出现Run-Time Check Failure #0错误

awaysrain 2005-02-01 05:57:15
错误信息

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.

(Press Retry to debug the application)
-----------------------------------------------------------------------------------
我的代码:

typedef char *(*GYQE)(char* buffer);
typedef int(*OmrSG)(char* buffer);

.....

OmrSG OmrS, OmrG;
GYQE gyqe;
HINSTANCE glib;
glib=LoadLibrary("omrdrive.dll");

if (glib!=NULL)
{
gyqe=(GYQE)GetProcAddress(glib,"gyqe");

OmrS=(OmrSG)GetProcAddress(glib,"OmrS");

OmrG=(OmrSG)GetProcAddress(glib,"OmrG");

jstring name;
char CommandStr[256],Buffer[256];
strcpy(CommandStr,"S FormatFile");
try{
OmrS(CommandStr);
strcpy(CommandStr,"/");
OmrS(CommandStr);
OmrG(Buffer);
if (!strncmp(Buffer,"OK",2))
{
strcpy(CommandStr,"001 /");
OmrS(CommandStr);//送取数据命令
OmrG(Buffer);//取返回字串
}
else
{
strcpy(CommandStr,"-/");
OmrS(CommandStr);
}
}
catch(CException* lpExp)
{

}


AfxMessageBox(Buffer);
}

if (!gyqe)
FreeLibrary(glib);







----------------------------------------------------------------------------------
那个dll的文档中这样说明

1. Microsoft Virtual C 6.0实例

int OmrS(char * CommandStr)

int OmrG(char * Buffer)  (PowerBuilde 中用char * PBOmrG(char * Buffer))

两个函数完成,或由char * gyqe(char * Buffer)一个函数完成。

实例:

//动态加载动态链接库OMRDRIVE.DLL

typedef char * ( * GYQE)(char * buffer);

typedef int( * OmrSG)(char * buffer);

OmrSG OmrS, OmrG;

GYQE gyqe;

HINSTANCE glib;

glib=LoadLibrary("OMRDRIVE.DLL");

if (glib!=NULL) {

gyqe=(GYQE)GetProcAddress(glib,"gyqe");

OmrS=(OmrSG)GetProcAddress(glib,"OmrS");

OmrG=(OmrSG)GetProcAddress(glib,"OmrG");

if (!gyqe) {

FreeLibrary(glib);

return;

}

}

else

return;

......

char CommandStr[256],Buffer[256];

strcpy(CommandStr,"S FormatFile"); //送格式命令

strcpy(CommandStr,"/");

OmrS(CommandStr); //送格式命令

OmrG(Buffer); //取读卡返回字串

//gyqe(CommandStr); //可以代替OmrS、OmrG

if (!strncmp(Buffer,"OK",2)){

strcpy(CommandStr,"001 /");

OmrS(CommandStr); //送取数据命令

OmrG(Buffer); //取返回字串



else{

strcpy(CommandStr,"-/");

OmrS(CommandStr);

}

...全文
3925 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
whwjn 2005-02-02
  • 打赏
  • 举报
回复
你怎么可以发200分?
sboom 2005-02-02
  • 打赏
  • 举报
回复
在DLL中的每个导出函数都要像下面这样

extern "C" __declspec(dllexport)
int fun()
{
}
不要漏掉extern "C"

不同IDE编写的DLL互相调用会有问题,堆管理器不同.
awaysrain 2005-02-02
  • 打赏
  • 举报
回复
我试了,管用,稍后结贴,感谢大家了
我要是把代码写在另外一个dll供java调用也是这样写吧?
吹泡泡的小猫 2005-02-02
  • 打赏
  • 举报
回复
把函数指针声明改成一下试试:

typedef char * (WINAPI * GYQE)(char * buffer);

typedef int(WINAPI * OmrSG)(char * buffer);

WINAPI也可以换成__stdcall试试
awaysrain 2005-02-02
  • 打赏
  • 举报
回复
如果是__stdcall的话该怎么处理?
我以前没有搞过c++,这个dll本来是要在java中用jni调用的,需要用c++重新包装一下才能在java中使用,后来发现在c++中就有问题
DentistryDoctor 2005-02-02
  • 打赏
  • 举报
回复
The value of ESP was not properly saved across a function call.应该是调用约定的问题。
用于非VC开发工具的DLL,导出函数的调用约定应该是__stdcall.(可参考<Windows核心编程>CH22)
awaysrain 2005-02-02
  • 打赏
  • 举报
回复
名称 值 类型
OmrS 0x01071000 int (char *)*
Omrs 0x01071020 int (char *)*
gyqe 0x010710c0 char * (char *)*

我发现一调用OmrS(CommandStr);完就报Run-Time Check Failure #0错误
调用omrs能够提示未连接(dll是omr读卡器的驱动,如果没有连上设备就提示未联机),但是调用完就出错,是不是清理堆栈的方式不对啊?
xuzheng318 2005-02-02
  • 打赏
  • 举报
回复
#define WINAPI __stdcall
flyelf 2005-02-02
  • 打赏
  • 举报
回复
请详细询问该动态库接口的调用约定,估计这是一个__stdcall的
老夏Max 2005-02-02
  • 打赏
  • 举报
回复
感觉没有什么可疑的地方,如果DLL不能更改,你跟踪一下:
gyqe=(GYQE)GetProcAddress(glib,"gyqe");

OmrS=(OmrSG)GetProcAddress(glib,"OmrS");

OmrG=(OmrSG)GetProcAddress(glib,"OmrG");

看看这个几个的函数指针获得的值是否正确。判断正确以后再使用。
awaysrain 2005-02-02
  • 打赏
  • 举报
回复
to whwjn(菜鸟学飞)
呵呵,放200分挺麻烦的
awaysrain 2005-02-02
  • 打赏
  • 举报
回复
那个dll是人家已经写好的,我不能修改那个dll
没有别的办法了吗?

我的环境是vs2003
吹泡泡的小猫 2005-02-02
  • 打赏
  • 举报
回复
如果java的默认调用是__stdcall就可以

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧