|
VS2005+ARX2008向导生成项目的时候,选上.Net mixed managed code。
由于.Net初始化的时候,可能会和DLL入口函数DllMain冲突。
首先得去掉入口函数,连接选项打开NoEntry. 这样就编译通过,但去掉入口函数的同时,产生两个问题:
1、此DLL的C运行库没初始化,静态,全局变量不能被正确使用,AutoCAD下load此DLL(ARX)的时候可能会致命错误;
2、_hdllInstance未初始化,DLL资源没法使用,对话框,图标,字符串全部Load失败,CAcModuleResourceOverride也失败。
解决第1个问题:分别在On_kInitAppMsg、和On_kUnloadAppMsg下调用__crt_dll_initialize,__crt_dll_terminate;
第2个问题,AfxGetInstanceHandle,GetModuleHandle都不好使。最后才查到利用VirtualQuery调用MEMORY_BASIC_INFORMATION,取其AllocationBase作为_hdllInstance。
网友实现:
#if _MSC_VER >= 1300 // for VC 7.0
// from ATL 7.0 sources
#ifndef _delayimp_h
extern "C" IMAGE_DOS_HEADER __ImageBase;
#endif
#endif
HMODULE GetCurrentModule()
{
#if _MSC_VER < 1300 // earlier than .NET compiler (VC 6.0)
MEMORY_BASIC_INFORMATION mbi;
static int dummy;
VirtualQuery( &dummy, &mbi, sizeof(mbi) );
return reinterpret_cast<HMODULE>(mbi.AllocationBase);
#else // VC 7.0
// from ATL 7.0 sources
return reinterpret_cast<HMODULE>(&__ImageBase);
#endif
}
《WINDOWS核心编程》里面的源代码:
/******************************************************************************
Module: ImgWalk.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
#include "..\CmnHdr.h" /* See Appendix A. */
#include <tchar.h>
#include "stdio.h"
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad) {
if (fdwReason == DLL_PROCESS_ATTACH) {
char szBuf[MAX_PATH * 100] = { 0 };
PBYTE pb = NULL;
MEMORY_BASIC_INFORMATION mbi;
while (VirtualQuery(pb, &mbi,sizeof(mbi)))
{
int nLen;
char szModName[MAX_PATH];
if (mbi.State == MEM_FREE)
mbi.AllocationBase = mbi.BaseAddress;
if ((mbi.AllocationBase == hinstDll) ||
(mbi.AllocationBase != mbi.BaseAddress) ||
(mbi.AllocationBase == NULL)) {
// Do not add the module name to the list
// if any of the following is true:
// 1. If this region contains this DLL
// 2. If this block is NOT the beginning of a region
// 3. If the address is NULL
nLen = 0;
} else {
nLen = GetModuleFileNameA((HINSTANCE) mbi.AllocationBase,
szModName, chDIMOF(szModName));
}
if (nLen > 0) {
wsprintfA(strchr(szBuf, 0), "\n%p--%08X--=%s",
mbi.AllocationBase,mbi.RegionSize, szModName);
}
pb += mbi.RegionSize;
}
chMB(&szBuf[1]);
}
return(TRUE);
}
|
|
|