现在是在一个动态库中动态加载另一个库,代码如下:
#include "stdafx.h"
#include "SmsDll.h"
#include <string.h>
#include <stdio.h>
BOOL g_bStart = false;typedef int (SmsSendOnModem)(char* strNum, char* strCon);SmsSendOnModem* g_pFuncSend; HINSTANCE g_hInstance;
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
 )
{
    switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
g_hInstance = ::LoadLibrary("SmsModem.dll");
//  if (g_hInstance)
//  {
//  g_pFuncSend = (SmsSendOnModem*)::GetProcAddress(g_hInstance, "SmsSendOnModem");
//  if (NULL == g_pFuncSend)
//  {
//  return FALSE;
//  }
//  else
//  {
//  g_bStart = TRUE;
//  }
//  }
//  break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
{
break;
}
case DLL_PROCESS_DETACH:
{
::FreeLibrary(g_hInstance);
break;
}
    }
    return TRUE;
}TESTDLL_API int func()
{
return 1;
}只要加了这一句(g_hInstance = ::LoadLibrary("SmsModem.dll");),调用完哪怕是一个空函数,也会异常。

解决方案 »

  1.   

    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    ...
      

  2.   

    KERNEL32! 76bcf05d()
    CSyncObject::~CSyncObject() line 41 + 11 bytes
    CCriticalSection::~CCriticalSection() line 42 + 42 bytes
    CSimpleMutex::~CSimpleMutex() line 40 + 8 bytes
    $E34() + 19 bytes
    doexit(int 0, int 0, int 1) line 353
    _cexit() line 294 + 11 bytes
    _CRT_INIT(void * 0x179a0000, unsigned long 0, void * 0x00000001) line 157
    _DllMainCRTStartup(void * 0x179a0000, unsigned long 0, void * 0x00000001) line 252 + 17 bytes
    NTDLL! 7774af24()
    NTDLL! 77753852()
    NTDLL! 777537c5()
    KERNEL32! 76bd2b04()
    JAVA! 00407454()
    JAVA! 004075b9()
    KERNEL32! 76bd1194()
    NTDLL! 7774b3f5()
    NTDLL! 7774b3c8()以上是调试时,堆栈中的提示信息
      

  3.   


    g_hInstance = ::LoadLibrary("SmsModem.dll");
    if (g_hInstance)
    {
    g_pFuncSend = (SmsSendOnModem*)::GetProcAddress(g_hInstance, "SmsSendOnModem");换成g_pFuncSend = GetProcAddress(GetModuleHandle(TEXT("SmsModem.dll")), "SmsSendOnModem");
    试下
      

  4.   

    就是说2个case合并:
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    break;
      

  5.   


    case DLL_PROCESS_ATTACH:
    {
    g_hInstance = ::LoadLibrary("SmsModem.dll");
    if (g_hInstance)
    {
    g_pFuncSend = (SmsSendOnModem*)::GetProcAddress(g_hInstance, "SmsSendOnModem");
    if (NULL == g_pFuncSend)
    {
    return FALSE;
    }
    else
    {
    g_bStart = TRUE;
    }
    }
    }
    case DLL_THREAD_ATTACH:
    {
    break;
    }这样子吗?
    问题一样存在!
      

  6.   

    就是说2个case合并:
    case DLL_PROCESS_ATTACH://fall through 没 break;case DLL_THREAD_ATTACH:
    break;
      

  7.   

    LoadLibrary()加载dll不成功????
      

  8.   

    注意这里的条约调用约定_stdcall不要忘记加(不然会引会esp出错) ,我这份代码测试没有问题!#include <windows.h>typedef int (_stdcall *MyMessageBox)(HWND,LPCTSTR,LPCTSTR,UINT);MyMessageBox    mybox;
    HINSTANCE       hInst;BOOL WINAPI DllMain(HANDLE hModule, DWORD dwCallType, LPVOID lpReserved)
    {
        switch (dwCallType) {
            case DLL_PROCESS_ATTACH:
                break;
            case DLL_THREAD_ATTACH:
            case DLL_THREAD_DETACH:
            case DLL_PROCESS_DETACH:
                hInst = LoadLibrary("user32.dll");
                mybox = (MyMessageBox)GetProcAddress(hInst,"MessageBoxA");
                if(mybox)
                {
                    mybox(NULL,"Hello World !",NULL,NULL);
                }
                break;
        }
        return TRUE;
    }
      

  9.   

    详情请参考:静态与动态加载Dll [示例代码]
      

  10.   

    Nafxcwd.lib Libcmtd.lib ws2_32.lib wldap32.lib 会不会跟动态库的编译选项有关?
    被加载的动态库的Link选项见上面。
      

  11.   

    这些是编译器默认给你的,相当于缺省加载的lib,跟你的问题应该没关系
      

  12.   

    检查了dll和你调用的dll的函数约定是否一致...
      

  13.   

    Win32的动态库,不是MFC的。不过动态库中有些函数里调用了部分MFC的一些功能。
    所以编译时,Link选项才会根据提示调整。
      

  14.   

    问题原因找到,问题已经解决。
    原因是动态库中从MFC的临界段类派生了一个类,并定义了一个全局变量。
    造成异常是全局变量析构时发生。
    至于为什么会发生,因为时间问题,暂时没有细究。谢谢各位!