现在是在一个动态库中动态加载另一个库,代码如下:
#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");),调用完哪怕是一个空函数,也会异常。
#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");),调用完哪怕是一个空函数,也会异常。
case DLL_THREAD_ATTACH:
...
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()以上是调试时,堆栈中的提示信息
g_hInstance = ::LoadLibrary("SmsModem.dll");
if (g_hInstance)
{
g_pFuncSend = (SmsSendOnModem*)::GetProcAddress(g_hInstance, "SmsSendOnModem");换成g_pFuncSend = GetProcAddress(GetModuleHandle(TEXT("SmsModem.dll")), "SmsSendOnModem");
试下
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
break;
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;
}这样子吗?
问题一样存在!
case DLL_PROCESS_ATTACH://fall through 没 break;case DLL_THREAD_ATTACH:
break;
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;
}
被加载的动态库的Link选项见上面。
所以编译时,Link选项才会根据提示调整。
原因是动态库中从MFC的临界段类派生了一个类,并定义了一个全局变量。
造成异常是全局变量析构时发生。
至于为什么会发生,因为时间问题,暂时没有细究。谢谢各位!