刚上班不久,给我一个小活,做一个IE插件,需要调用一个DLL中的几个导出函数,
有几个函数还好,有一个总是不成功,我怀疑是DLL有问题。
在那个写DLL的人电脑上,直接调用她的源码没有问题。
但是在我的电脑上调用DLL就会出错。
值得注意的一点是,她给我的关于导出函数的头文件里的函数是这样声明的,
#ifdef MAKEKEY_EXPORTS
#define MAKEKEY_API __declspec(dllexport)
#else
#define MAKEKEY_API __declspec(dllimport)
#endifMAKEKEY_API DWORD Base64_Key(SafeSpace *safespace,SafeSpace_base64 *safespace_base64);
但是我调用的时候发现,定义函数指针时(我采用动态加载的方式调用DLL中的导出函数)采用_stdcall方式会报错,所以我只能采用_cdecl这种方式声明,
但是就是最后的结果不正确。就是这个Base64_Key函数有问题,直接导致后面的函数得不到正确的结果。
请问大家,到底是什么原因导致不能正确调用?函数指针已经获得,没有问题。就是返回的结果不对。
大家帮帮忙。这个程序我调了几天了,现在我还是试用期,要是因为这个把我辞了,我就亏大了。
大家给看看你

解决方案 »

  1.   

    如果是动态加载需要注意:
    1.Dll是否需要初始化?忘记初始化了(看你如何调用);
    2.传递的参数是否正确;
    3.DllFun函数是否返回了局部数据
      

  2.   

    如果DLL有用到COM的东西,注意COM的初始化.
    其他基本如楼上的朋友所说.
      

  3.   

    4楼说的我明白
    奇怪的是 她是这么调试的
    用我的代码连接她的源码 
    最后结果竟然是正确的
    但是我直接调用DLL导出函数就是不对
    调试发现其中一个函数就是加密函数base64_key,返回的结果数据有丢失
    几个key都丢失了
      

  4.   

    纯猜测,注意到传递的参数是指针,相应的内存是不是遵循了谁申请 谁释放的原则。
    如果是该指针是对方DLL申请的对象,那对方DLL应该提供对应的释放函数.
      

  5.   

    SafeSpace_base64 *safespace_base64 = new SafeSpace_base64 ;
    if (!safespace_base64)
    {
    return S_FALSE;
    }
    ZeroMemory(safespace_base64,sizeof(SafeSpace_base64));

    SafeSpace *Usersafespace = new SafeSpace;
    if (Usersafespace == NULL)
    {
    return S_FALSE;
    }
    ZeroMemory(Usersafespace,sizeof(SafeSpace));

    SafeSpace *User_safespace = new SafeSpace;
    if (User_safespace == NULL)
    {
    return S_FALSE;
    }
    ZeroMemory(User_safespace,sizeof(SafeSpace));

    SafeSpace_base64 *usersafespace_base64 = new SafeSpace_base64;
    if (usersafespace_base64 == NULL)
    {
    return S_FALSE;
    }
    ZeroMemory(usersafespace_base64,sizeof(SafeSpace_base64));

    PartOfSafeSpace_base64 *partofsafespace_base64 = new PartOfSafeSpace_base64;
    if (partofsafespace_base64 == NULL)
    {
    return S_FALSE;
    }
    ZeroMemory(partofsafespace_base64,sizeof(PartOfSafeSpace_base64));

            ExportKeyInfo("11111111",safespace,0,&err);
            MakeRootKey("lmm",1,"rootadmin",1,safespace,&err);
    Encrypt_Key("11111111",safespace,&err);
    Base64_Key(safespace,safespace_base64);
    cout<<safespace_base64->usercert<<endl;
    cout<<safespace_base64->WorkKey<<endl;
    cout<<safespace_base64->PriKey<<endl;
    cout<<safespace_base64->rsauserkey<<endl;
    cout<<safespace_base64->rootcert<<endl;
    前几个函数还正常,但是到Base64_Key这里就出错了 ,几个key的值是空的,这个函数是加密用的,safespace和这个结构体里面的参数还在,不知道是怎么回事?
    MAKEKEY_API DWORD Base64_Key(SafeSpace *safespace,SafeSpace_base64 *safespace_base64)
    {
    //对即将写入数据库中的数据base64,通过接口导出
    int len; ZeroMemory(safespace_base64,sizeof(SafeSpace_base64));
    base64(safespace->rsauserkey,1024,safespace_base64->rsauserkey,&len);
    base64(safespace->WorkKey,128,safespace_base64->WorkKey,&len);
    base64(safespace->PriKey,128,safespace_base64->PriKey,&len); if(safespace->rootcert[0] == '-')
    memcpy(safespace_base64->rootcert,safespace->rootcert,sizeof(safespace->rootcert));
    else if(safespace->usercert[0] == '-')
    memcpy(safespace_base64->usercert,safespace->usercert,sizeof(safespace->usercert));
    return 0;
    }
    int base64(unsigned char* in,int inlen,unsigned char *out,int* outlen){ EVP_ENCODE_CTX     ectx,dctx; int  total,ret; //SM_EVP_EncodeInit(&ectx);
    EVP_EncodeInit(&ectx); total=0; EVP_EncodeUpdate(&ectx,out,outlen,in,inlen); total+=*outlen; EVP_EncodeFinal(&ectx,out+total,outlen); total+=*outlen; return 0;}
    大家看看吧
      

  6.   

    如你所说
    "在那个写DLL的人电脑上,直接调用她的源码没有问题。 
    但是在我的电脑上调用DLL就会出错。"
    我估计这句话有问题,
    你可以检测一下sizeof(SafeSpace_base64))的值,在两台电脑上一样不,因为多次用到,你看看
      

  7.   

    估计是传给内存ZeroMemory这个函数的第二个参数有问题
      

  8.   

    采用_stdcall方式会报错,所以我只能采用_cdecl这种方式声明?有你这么干的吗?你在别人的机上用_stdcall(成功),自己机上用_cdecl(不成功)?
      

  9.   

    lz,能够说说为何你_stdcall方式会出错么?
    印象中,dll函数都是_stdcall申明的。
      

  10.   

    调了一下午,终于搞明白是怎么回事,
    那个函数确实被调用了,函数的结果最后也计算出来了,但是不知道为什么指针指偏了,
    因为返回的结构体比输入的结构体大,大概两倍左右,但是成员都是一样的,只是每个成员差不多是输入结构体成员的两倍大小。
    不知道为什么会出现这种情况,大家遇到过这种情况吗?回复11楼:
    “采用_stdcall方式会报错,所以我只能采用_cdecl这种方式声明?有你这么干的吗? 你在别人的机上用_stdcall(成功),自己机上用_cdecl(不成功)?“是那个程序员告诉我 要_stdcall这么调用的,但是我今天看她的源代码,她并没有显示声明为_stdcall,因为默认是采用_cdecl方式,所以我也只能采用那种方式。
      

  11.   

    typedef struct tagSafeSpace
    {
    KEY_FPAGE key_fpage;
        unsigned char usercert[2048];       
    unsigned char centercert[2048];     
    unsigned char rootcert[2048];
    int WorkKeyAlgorithmIdentifer;        
    unsigned char WorkKey[128];        
    unsigned char PriKey[128];
    int rsauserkeyAlgorithmIdentifer;   
        unsigned char rsauserkey[1024];   
    unsigned char MotherKeyIdentifer;
    unsigned char other[127];
    } SafeSpace;
    typedef struct tagSafeSpace_base64
    {
    KEY_FPAGE key_fpage;
    unsigned char usercert[4096];      
    unsigned char centercert[4096];     
    unsigned char rootcert[4096];
    int WorkKeyAlgorithmIdentifer;     
    unsigned char WorkKey[256];         
    unsigned char PriKey[256];
    int rsauserkeyAlgorithmIdentifer;   
    unsigned char rsauserkey[2048];    
    unsigned char MotherKeyIdentifer;
    unsigned char other[127];
    } SafeSpace_base64;调用base64_key函数的结果是将SafeSpace里的rootcert赋给了SafeSpace_base64里的centercert,
    想问问大家怎么解决这个问题
      

  12.   

    写DLL的人告诉你用_stdcall,你就应该用_stdcall,具体是什么错?
      

  13.   

    但是我调用的时候发现,定义函数指针时(我采用动态加载的方式调用DLL中的导出函数)采用_stdcall方式会报错,所以我只能采用_cdecl这种方式声明, 
    动态加载什么时候需要本地声明_stdcal、_cdcal之类啊?
    你是隐式链接吗?如果隐式链接,两边必须完全一致。
      

  14.   

    昨晚终于搞明白了,是他们给我的头文件里的结构体变量不一致,
    那几个key应该都是2048的,
    源码是2048的,
    给我的结构体声明确实4096的,不出错才怪。
    气死我了,浪费我几天的时间
    搞得我差点绝望。
    幸好我把源码要来看了看,不然我就是调上一个月也调不出来啊
    根本没想到是这个原因。
    谢谢大家了
      

  15.   

    她告诉我说要_stdcall调用,但是她在源码里并没有这么声明,
    而如果没有显示声明,默认是_cdecl这种调用方式,所以是她误导了我
    我现在觉得对她有点失去信任,以后还是自己要小心
      

  16.   

    见证了CSDN论坛中强人们的强大,膜拜
      

  17.   

    哈哈,说明代码版本管理实在是太重要了,我也曾碰到过给的头文件和实际的dll不是一个版本的问题,当时气得我把整个内存全dump出来,他才服气然后查出来是他改了后忘了给我最新版本
      

  18.   

    多次遇到这样的问题了
    Dll publisher责任重大啊
      

  19.   

    项目开发中 对外数据结构和函数确定后一般不准改 否则很容易导致版本不一致的情况 而且查起来很费时间
    内存dump就服气了?不太明白
      

  20.   

    用dumpin 查看一下Base64_Key函数的导出名称
      

  21.   

    广州搬家公司
    广州搬家公司
    广州大众搬家公司
    广东搬家公司
    广州空调维修公司
    广州空调维修公司
    广州空调维修
    广州疏通公司
    广州疏通公司
    广州装饰公司
    www.gzbjxx.com
    www.020bjw.cn
    www.520banjia.cn
    www.520fuwu.cn
    www.gzktfw.cn
    www.gzstfw.cn
    www.020gzkt.cn
    www.520zhuangshi.cn
    www.520shutong.cn
    www.520kongtiao.cn
      

  22.   

    我来推荐一个java视频课程在线试听:http://www.cdlanhai.com/zxst/
      

  23.   

    哇,都看不懂哦,C++WINDOWS编程不是太懂哦
      

  24.   

    dll之间的传递参数最好不要用非标准类型
      

  25.   

    曾遇过同样问题,dll的发布与头文件不匹配,搞了2晚上,郁闷啊