- UID
- 2
- 精华
- 积分
- 7736
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
前面已经说过,MFC早期版本的CString实现没有使用ATL,而plugin.h要求编译时加入/J命令,或定义_CHAR_UNSIGNED宏,而ATL要求则相反。因此这个问题在VC6中不存在,而在VS2010及以上版本存在,目前我就测试了这几个版本。如何解决这个矛盾呢?今天我研究出一种方法。
#if宏在这里起了决定性作用,如果命令行定义/J则所有工程文件都默认定义_CHAR_UNSIGNED,那么我们退而求其次,只在必要处添加该定义,使用结束后取消定义,这样就不和ATL冲突了!!!下面是该宏用法:
#if !defined _CHAR_UNSIGNED
#define _CHAR_UNSIGNED
#define _ISCHARTYPEUNSIGNED 1
#else
#define _ISCHARTYPEUNSIGNED 0
#endif
#if _ISCHARTYPEUNSIGNED == 1
#undef _CHAR_UNSIGNED
#endif
我使用_ISCHARTYPEUNSIGNED 判断是否修改了_CHAR_UNSIGNED,如果原来未定义_CHAR_UNSIGNED,那么就在当前代码块定义该标志,块结束再改回去。如果原来定义过,则不用做任何操作。该代码要和MFC相关宏分开,因此
下面来测试,新建一个MFC的常规DLL,主文件中修改为如下形式:
- // MFCLibrary1.cpp : 定义 DLL 的初始化例程。
- //
- #include "stdafx.h"
- #include "MFCLibrary1.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #endif
- //
- //TODO: 如果此 DLL 相对于 MFC DLL 是动态链接的,
- // 则从此 DLL 导出的任何调入
- // MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
- // 该函数的最前面。
- //
- // 例如:
- //
- // extern "C" BOOL PASCAL EXPORT ExportedFunction()
- // {
- // AFX_MANAGE_STATE(AfxGetStaticModuleState());
- // // 此处为普通函数体
- // }
- //
- // 此宏先于任何 MFC 调用
- // 出现在每个函数中十分重要。这意味着
- // 它必须作为函数中的第一个语句
- // 出现,甚至先于所有对象变量声明,
- // 这是因为它们的构造函数可能生成 MFC
- // DLL 调用。
- //
- // 有关其他详细信息,
- // 请参阅 MFC 技术说明 33 和 58。
- //
- // CMFCLibrary1App
- BEGIN_MESSAGE_MAP(CMFCLibrary1App, CWinApp)
- END_MESSAGE_MAP()
- // CMFCLibrary1App 构造
- CMFCLibrary1App::CMFCLibrary1App()
- {
- // TODO: 在此处添加构造代码,
- // 将所有重要的初始化放置在 InitInstance 中
- }
- // 唯一的一个 CMFCLibrary1App 对象
- CMFCLibrary1App theApp;
- // CMFCLibrary1App 初始化
- BOOL CMFCLibrary1App::InitInstance()
- {
- CWinApp::InitInstance();
- return TRUE;
- }
- #if !defined _CHAR_UNSIGNED
- #define _CHAR_UNSIGNED
- #define _ISCHARTYPEUNSIGNED 1
- #else
- #define _ISCHARTYPEUNSIGNED 0
- #endif
- #include <Windows.h>
- #include "Plugin.h"
- #include <stdio.h>
- #pragma comment(lib,"ollydbg.lib")
- HINSTANCE hInst;
- HWND hOllyWnd;
- t_module* MainModule;
- extc int _export cdecl ODBG_Pluginmenu(int origin,char data[4096],void *item)
- {
- return 1;
- }
- extc int _export cdecl ODBG_Plugininit(int ollydbgversion,HWND hw, ulong *features)
- {
- return 0;
- }
- extc int _export cdecl ODBG_Plugindata(char shortname[32])
- {
- strcat(shortname,"testMFC");
- return 108;
- }
- #if _ISCHARTYPEUNSIGNED == 1
- #undef _CHAR_UNSIGNED
- #endif
复制代码
MFC扩展DLL例子:
- // dllmain.cpp : 定义 DLL 的初始化例程。
- //
- #include "stdafx.h"
- #include <afxwin.h>
- #include <afxdllx.h>
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #endif
- static AFX_EXTENSION_MODULE MFCLibrary2DLL = { NULL, NULL };
- extern "C" int APIENTRY
- DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
- {
- // 如果使用 lpReserved,请将此移除
- UNREFERENCED_PARAMETER(lpReserved);
- if (dwReason == DLL_PROCESS_ATTACH)
- {
- TRACE0("MFCLibrary2.DLL 正在初始化!\n");
-
- // 扩展 DLL 一次性初始化
- if (!AfxInitExtensionModule(MFCLibrary2DLL, hInstance))
- return 0;
- // 将此 DLL 插入到资源链中
- // 注意: 如果此扩展 DLL 由
- // MFC 规则 DLL (如 ActiveX 控件)隐式链接到,
- // 而不是由 MFC 应用程序链接到,则需要
- // 将此行从 DllMain 中移除并将其放置在一个
- // 从此扩展 DLL 导出的单独的函数中。使用此扩展 DLL 的
- // 规则 DLL 然后应显式
- // 调用该函数以初始化此扩展 DLL。否则,
- // CDynLinkLibrary 对象不会附加到
- // 规则 DLL 的资源链,并将导致严重的
- // 问题。
- new CDynLinkLibrary(MFCLibrary2DLL);
- }
- else if (dwReason == DLL_PROCESS_DETACH)
- {
- TRACE0("MFCLibrary2.DLL 正在终止!\n");
- // 在调用析构函数之前终止该库
- AfxTermExtensionModule(MFCLibrary2DLL);
- }
- return 1; // 确定
- }
- #if !defined _CHAR_UNSIGNED
- #define _CHAR_UNSIGNED
- #define _ISCHARTYPEUNSIGNED 1
- #else
- #define _ISCHARTYPEUNSIGNED 0
- #endif
- #include <Windows.h>
- #include "Plugin.h"
- #include <stdio.h>
- #pragma comment(lib,"ollydbg.lib")
- HINSTANCE hInst;
- HWND hOllyWnd;
- t_module* MainModule;
- extc int _export cdecl ODBG_Pluginmenu(int origin,char data[4096],void *item)
- {
- return 1;
- }
- extc int _export cdecl ODBG_Plugininit(int ollydbgversion,HWND hw, ulong *features)
- {
- return 0;
- }
- extc int _export cdecl ODBG_Plugindata(char shortname[32])
- {
- strcat(shortname,"testMFC");
- return 108;
- }
- #if _ISCHARTYPEUNSIGNED == 1
- #undef _CHAR_UNSIGNED
- #endif
复制代码 |
|