环境Visual Studio 2005 with SP1, XP SP2, GCC3.4.4因为需要用到MD5算法,加上本人实在是懒所以决定用Windows提供的MD5Init, MD5Update, MD5Final API来搞定,但是微软也够懒,这三个API连头文件都没提供所以我只好用LoadLibrary, GetProcAddress来搞定了。可是问题出现了,编译运行后提示:
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.
问题出在调用MD5Init的地方。反汇编,结果发现API函数返回的时候用了ret 4指令(MD5Init只有一个参数:指向MD5_CTX结构的指针)返回后发现VS生成的代码中加入了Add esp,4这样一条指令,ESP被错误的多加上了4个字节,因此出现了上面的问题。但是同样的代码我在用GCC3.4.4编译时却没有问题。
请问这个问题该如何解决。源代码如下://////////////md5.h///////////////////#pragma once#include <windows.h>typedef struct _MD5_CTX
{
ULONG i[2]; 
ULONG buf[4];
unsigned char in[64];
unsigned char digest[16];
} MD5_CTX;typedef void (*PMD5Init)(
MD5_CTX* context
);typedef void (*PMD5Update)(
MD5_CTX* context,
unsigned char* input,
unsigned int inlen
);typedef void (*PMD5Final)(
MD5_CTX* context
);////////////////////////md5.cpp////////////////
#include "stdafx.h"
#include "md5.h"void GetMD5Hash(MD5_CTX* md5)
{
HMODULE hmodule = LoadLibrary(TEXT("Cryptdll.dll"));
PMD5Init MD5Init = (PMD5Init)GetProcAddress(hmodule, "MD5Init");

MD5Init(md5);  //就是这里!!! FreeLibrary(hmodule);
}
int _tmain(int argc, _TCHAR* argv[])
{
MD5_CTX md5; GetMD5Hash(&md5); return 0;
}

解决方案 »

  1.   

    貌似要用stdcall,但是应该怎么写啊
      

  2.   

    已搞定
    typedef  void  (__stdcall *PMD5Init)(  
               MD5_CTX*  context  
    );  散分了~大家来接分吧~~~
      

  3.   

    接分。我有MD5的RSA提供的源代码,不过看来楼主用不到了。
      

  4.   

    开始的时候查了半天的MSDN,查来查去都不知道那个__stdcall在用typedef的时候应该插在哪儿,然后就以为可能不用加也行吧,结果就出错了。后来上网搜了一下,发现cdcel和stdcall的区别就在于一个是由调用者一个是由被调用者清理堆栈,看来一定是要用stdcall了,想了半天才想到,typedef void __stdcall *PMD5Init不行可以这样啊typedef  void  (__stdcall *PMD5Init),果真不出我所料,这次就成功了~呵呵,谢谢各位了~结贴~~~