中易网

创建动态链接库里可以有宏定义吗

答案:1  悬赏:0  
解决时间 2021-12-29 17:14
创建动态链接库里可以有宏定义吗
最佳答案
一、DLL动态链接库如何共享数据
上次有人问起一个关于DLL编写的问题:他创建了一个DLL动态链接库,里面写了一个鼠标钩子,用于监视鼠标左键的点击;另外创建了一个普通MFC应用程序,里面可以通过点击按钮加载这个DLL库并安装钩子。钩子的效果是:当用户在屏幕的任何地方点击鼠标左键,都会导致MFC应用程序里面的计数器的加一。可是,程序编写完后,问题出现了:当他在MFC应用程序窗口内单击鼠标左键,计数器能够成功自增;可是一旦在窗口之外的地方左击,则不能自增,即使他把那个MFC应用程序设置为了“顶级窗口”——即无论是否有焦点,始终在桌面最前端。
我开始也很不解,怀疑他是否正确创建了钩子。钩子(hook)有两种,即进程相关钩子,和全局钩子。进程相关钩子只对指定的进程起作用,例如:
SetWindowsHookEx(WH_GETMESSAGE,HookProc, hMod, dwThreadId);
而全局钩子则对所有进程起作用,例如:
SetWindowsHookEx(WH_GETMESSAGE,HookProc, hMod, NULL);
仔细查看他的代码后,发现钩子编写是正确的,将这种可能排除。
最后终于发现——这主要得益于网友Hc1的提醒,在这里说一声谢谢!——原来是在DLL工程中,有一个和计数器密切相关的变量i没有共享,也就是说,对于不同的进程,他所看到的i是不同的。我们知道,动态链接库最大的好处是不同的进程可以共享,节省内存。但是,这种共享是有条件的,也就是说,被允许共享的代码和变量才能真正被共享,否则默认的是不共享。所以在这里我们需要将i设置为共享:
#pragma data_seg(“.MyData”)
int i=0;
#pragma data_seg()
注意,被共享的变量一定要初始化,否则,编译器仍然会把它作为非共享变量。
最后,在DEF文件中添加如下语句:
SECTIONS
.MyData READ WRITE SHARED
“.MyData”表示这段共享数据的名字,可以任意,甚至是中文。
编译结束后,我们可以通过命令行运行dumpbin命令查看dll的导出情况,可以发现确实导出了数据段“.MyData”。

二、如何创建纯资源DLL
有时候,我们需要创建纯资源的DLL文件,用来储存一些资源,例如我们可以通过创建纯资源DLL来解决软件的国际化问题(DLL里面包含多国语言资源,就可以实现安装时选择用户所使用的语言这一个性化功能)。编写纯资源DLL要比编写一般的DLL简单的多,例如不需要编写DEF导出文件等。
首先新建一个Win32 DLL工程。然后用“新建”命令创建一个“Resource Script”文件,在出现的RS编辑窗口中,单击鼠标右键,就可以添加各种资源,并可以对资源进行编辑。接着,在通过“新建”创建一个Cpp文件。虽然,后面我们会看到,我们可以不对这个空白的Cpp源文件进行任何操作,但是我们仍然需要新建一个Cpp,原因我不太清除,是实验测试的时候发现的。最后,单击“Project”,再“Settings”,再“Link”,在“Project Options”编辑框里面,添加“/noentry”,以避免编译器自动为我们的资源DLL文件添加默认的_main或者DllMain入口函数。事实上,经过测试,不设置这个“noentry”,工程照样可以成功编译,也可以在其他工程中使用正常,但是大小却要增加很多,对于纯资源的DLL文件来说,这些增加的体积毫无必要,所以我们还是需要手动添加这么一个命令。
如何在在普通MFC应用程序工程中使用我们写好的纯资源DLL呢?首先,需要定义资源宏。例如,在纯资源的DLL里面有一张名为:IDB_BITMAP1的位图,那么一般VC编译器默认的资源宏定义是从100开始的,所以在纯资源DLL里面有这样的宏:
#define IDB_BITMAP1 101
这句宏定义是在Resource.h头文件当中的。
那么我们也要在MFC应用程序中定义同样的宏,否则无法加载这个位图。
然后,我们需要加载DLL文件(在这里,我们认为开始时创建的动态链接库为A.dll):
HINSTANCE hDll=LoadLibrary("A.dll");
if(hDll==NULL)
{
MessageBox(“Load Error!”);
return;
}
加载并测试是否成功,否则返回。
然后,我们就可以像在正常MFC应用程序里面添加资源一样加载DLL里面的资源了:
HBITMAP hBit=(HBITMAP)::LoadImage(hDll,
MAKEINTRESOURCE(IDB_BITMAP1),
IMAGE_BITMAP,
0, 0,
LR_DEFAULTCOLOR);
if(hBit==NULL)
{
MessageBox("hBit is NULL");
return;
}
CBitmap bitmap;
bitmap.Attach(hBit);
CClientDC dc(this);
CDC dcCom;
dcCom.CreateCompatibleDC(&dc);
dcCom.SelectObject(&bitmap);
dc.BitBlt(0, 0, 500, 500, &dcCom, 0, 0, SRCCOPY);
ReleaseDC(&dcCom);
当然,最后在使用完DLL之后,不要忘了卸载DLL:
FreeLibrary(hDll);
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
1,How do your father go to work?
淘宝退一件衣服,外面这个包装用的塑料袋不见
鸡鸣乡居委会地址在哪,我要去那里办事
跑楼儿的意思是什么啊?请解释下!
牛车的意思是什么?牛车的释义是什么啊?
小锅一锅多星的安装详解
刚买来的衣服要不要洗啊?
我想坐着的时候坐正,背直一点,但又不要显得
申请WF需要开公司,但不知道经营范围应该怎么
我做平面设计工作已经有三年,想转行,不知道
林海陶瓷超市地址有知道的么?有点事想过去
main(){int p[8]={11,12,13,14,15,16,17,18},
叹的成词语有哪些
洋落的意思是什么?洋落的释义是什么啊?
泼风刀的意思是什么啊?请解释下!
推荐资讯
请问伊婉玻尿酸隆鼻如何?
营业执照忘记年检拉黑了,又不能换烟草证,怎么
iwatch输入密码后要求按钮,按哪个钮啊?
各银行有哪些卡是单芯片卡
黃場的意思是什么?黃場的释义是什么啊?
三点水加宗是什么组什么词
小猫快满月了 之前睁过眼睛 之后上火 被眼屎
原样的意思是什么啊?请解释下!
红鹦鹉贴着鱼缸的边不停的原地游??然后一只只
做假体下巴多长时间可以刷牙
医生被打了打一成语
老婆产后肚脐周围有很深的色素沉淀,黑呼呼的
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?