我在调用一个CB写的DLL过程中,碰到这样一个奇怪的问题,急
编译没有问题,运行时,如果在InitDialog调用DLL中的函数不报错,但如果将调用DLL函数的部分写到别的地方去就出错。为什么?
//Send_Command_Word
typedef bool(*pFunction)(int portNumber,int iPictureCounts, 
int iScreenID,int iPageID, int iMoveStyle, int iMoveSpeed, int iPauseTime);


pFunction pConfig = NULL;

mlib = LoadLibrary(TEXT("TMH-at90.dll"));
if(mlib)
{
AfxMessageBox("success"); pConfig = (pFunction)::GetProcAddress((HMODULE)mlib,"Send_Command_Word"); pConfig(1,1,85,0,1,1,1);
}
else
{
AfxMessageBox("faild");
}
错误提示:
0x0000000指令引用0X00000内存,该内存不能为“read"

解决方案 »

  1.   

    看他的意思是GetProcAddress没有返回值,他找不到那个函数啊。
    不知道为什么,最好能有更详细的代码。
      

  2.   

    与调用相关的代码全部在这里了,已经找到函数地址了。而且我在InitDialog里调用是没有问题的。
      

  3.   

    不会是pConfig 的作用域问题吧,好象太离谱了。
      

  4.   

    写到别的地方去就出错:你到底写到那里了!看你写的是Send_command_word是不是用了句柄什么的?把Send_command_word列出来。
      

  5.   

    我顺手用 BCB6 写了 dll, 再用 VC6 调这个 dll 无论放哪里都还好啊。不信你试试:
    [BCB6_Dll]
    extern "C" __declspec(dllexport) bool __stdcall Send_Command_Word(int ,int , int ,int , int , int , int );bool __stdcall Send_Command_Word(int portNumber,
                             int iPictureCounts,
                             int iScreenID,
                             int iPageID,
                             int iMoveStyle,
                             int iMoveSpeed,
                             int iPauseTime)
    {
      char stemp[4];
      itoa(portNumber, stemp, 10);
      WritePrivateProfileString("port", "portNumber", stemp, "c:\\temp.ini");
      itoa(iPictureCounts, stemp, 10);
      WritePrivateProfileString("port", "iPictureCounts", stemp, "c:\\temp.ini");
      itoa(iScreenID, stemp, 10);
      WritePrivateProfileString("port", "iScreenID", stemp, "c:\\temp.ini");
      itoa(iPageID, stemp, 10);
      WritePrivateProfileString("port", "iPageID", stemp, "c:\\temp.ini");
      itoa(iMoveStyle, stemp, 10);
      WritePrivateProfileString("port", "iMoveStyle", stemp, "c:\\temp.ini");
      itoa(iMoveSpeed, stemp, 10);
      WritePrivateProfileString("port", "iMoveSpeed", stemp, "c:\\temp.ini");
      itoa(iPauseTime, stemp, 10);
      WritePrivateProfileString("port", "iPauseTime", stemp, "c:\\temp.ini");
      
      return true;
    }[VC6_Call_Dll]
    void CMyCallDlg::OnButtonQ20031204() 
    {
    typedef bool (__stdcall *pFunction)(int ,int , int ,int , int , int , int );

    pFunction pConfig = NULL;
    HINSTANCE mlib = LoadLibrary(TEXT("TMH-at90.dll"));
    if(mlib != NULL)
    {
    pConfig = (pFunction)GetProcAddress(mlib, "Send_Command_Word");
    if (pConfig != NULL)
    (pConfig)(1,1,85,0,1,1,1);
    }
    else
    {
    AfxMessageBox("faild");
    }
    FreeLibrary(mlib);
    }
    哦,对了有点不同的是,我用了 __stdcall
      

  6.   

    你用__cdecl 调用约定试试
    用__stdcall我遇到过在函数退出的时候错误---------
      ++C++
    ---------
      

  7.   

    原因就是楼上说的
      2. 调用约定:
        __cdecl 缺省
          是 Borland C++ 的缺省的 C 格式命名约定,它在标识符前加一下划线,以保留
        它原来所有的全程标识符。参数按最右边参数优先的原则传递给栈,然后清栈。
            extaern "C" bool __cdecl TestFunction();
          在 def 文件中显示为 
            TestFunction @1
          注释: @1 表示函数的顺序数,将在“使用别名”时使用。    __pascal Pascal格式
          这时函数名全部变成大写,第一个参数先压栈,然后清栈。
            TESTFUNCTION @1 //def file    __stdcall 标准调用
          最后一个参数先压栈,然后清栈。
            TestFunction @1 //def file    __fastcall 把参数传递给寄存器
          第一个参数先压栈,然后清栈。
            @TestFunction @1 //def file  3. 解决调用约定:
          Microsoft 与 Borland 的 __stdcall 之间的区别是命名方式。 Borland 采用
        __stdcall 的方式去掉了名字起前的下划线。 Microsoft 则是在前加上下划线,在
        后加上 @ ,再后跟为栈保留的字节数。字节数取决于参数在栈所占的空间。每一个
        参数都舍入为 4 的倍数加起来。这种 Miocrosoft 的 DLL 与系统的 DLL 不一样。
      

  8.   

    BCB还不一样呀?没用过 学习。
      

  9.   

    typedef bool(__stdcall *pFunction)(int portNumber,int iPictureCounts, 
    int iScreenID,int iPageID, int iMoveStyle, int iMoveSpeed, int iPauseTime);在vc中默认(省略)的调用方式__cdecl 
    而你的dll是 __stdcall 所以在前面加上__stdcall