没有合适的资源?快使用搜索试试~ 我知道了~
DLL学习教程.doc
5星 · 超过95%的资源 需积分: 9 9 下载量 53 浏览量
2010-10-18
21:25:40
上传
评论
收藏 73KB DOC 举报
温馨提示
试读
16页
本文对通用的DLL技术做了一个总结,并提供了源代码打包下载,下载地址为: http://www.blogjava.net/Files/wxb_nudt/DLL_SRC.rar
资源详情
资源评论
资源推荐
摘自百度文库,网址:http://wenku.baidu.com/view/afd7866527d3240c8447efa6.html
DLL 编写教程一(精)2010 年 01 月 04 日 星期一 04:00 P.M.DLL 编写教程
半年不能上网,最近网络终于通了,终于可以更新博客了,写点什么呢?决定最近写一个
编程技术系列,其内容是一些通用的编程技术。例如 DLL,COM,Socket,多线程等等。
这些技术的特点就是使用广泛,但是误解很多;网上教程很多,但是几乎没有什么优质良
品。我以近几个月来的编程经验发现,很有必要好好的总结一下这些编程技术了。一来对
自己是总结提高,二来可以方便光顾我博客的朋友。
好了,废话少说,言归正传。第一篇就是《DLL 编写教程》,为什么起这么土的名字呢?
为什么不叫《轻轻松松写 DLL》或者《DLL 一日通》呢?或者更 nb 的《深入简出 DLL》
呢?呵呵,常常上网搜索资料的弟兄自然知道。
本文对通用的 DLL 技术做了一个总结,并提供了源代码打包下载,下载地址为:
http://www.blogjava.net/Files/wxb_nudt/DLL_SRC.rar
DLL 的优点
简单的说,dll 有以下几个优点:
1) 节省内存。同一个软件模块,若是以源代码的形式重用,则会被编译到不同的可执行
程序中,同时运行这些 exe 时这些模块的二进制码会被重复加载到内存中。如果使用 dll,
则只在内存中加载一次,所有使用该 dll 的进程会共享此块内存(当然,像 dll 中的全局变
量这种东西是会被每个进程复制一份的)。
2) 不需编译的软件系统升级,若一个软件系统使用了 dll,则该 dll 被改变(函数名不
变)时,系统升级只需要更换此 dll 即可,不需要重新编译整个系统。事实上,很多软件都
是以这种方式升级的。例如我们经常玩的星际、魔兽等游戏也是这样进行版本升级的。
3) Dll 库可以供多种编程语言使用,例如用 c 编写的 dll 可以在 vb 中调用。这一点上
DLL 还做得很不够,因此在 dll 的基础上发明了 COM 技术,更好的解决了一系列问题。
最简单的 dll
开始写 dll 之前,你需要一个 c/c++编译器和链接器,并关闭你的 IDE。是的,把你的 VC
和 C++ BUILDER 之类的东东都关掉,并打开你以往只用来记电话的记事本程序。不这样
做的话,你可能一辈子也不明白 dll 的真谛。我使用了 VC 自带的 cl 编译器和 link 链接器,
它们一般都在 vc 的 bin 目录下。(若你没有在安装 vc 的时候选择注册环境变量,那么就立
刻将它们的路径加入 path 吧)如果你还是因为离开了 IDE 而害怕到哭泣的话,你可以关闭
这个页面并继续去看《VC++技术内幕》之类无聊的书了。
最简单的 dll 并不比 c 的 helloworld 难,只要一个 DllMain 函数即可,包含 objbase.h 头文件
(支持 COM 技术的一个头文件)。若你觉得这个头文件名字难记,那么用 windows.H 也
可以。源代码如下:dll_nolib.cpp
#include <objbase.h>
#include <iostream.h>
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved)
{
HANDLE g_hModule;
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
cout<<"Dll is attached!"<<endl;
g_hModule = (HINSTANCE)hModule;
break;
case DLL_PROCESS_DETACH:
cout<<"Dll is detached!"<<endl;
g_hModule=NULL;
break;
}
return true;
}
其中 DllMain 是每个 dll 的入口函数,如同 c 的 main 函数一样。DllMain 带有三个参数,
hModule 表 示 本 dll 的 实 例 句 柄 ( 听 不 懂 就 不 理 它 , 写 过 windows 程 序 的 自 然 懂 ),
dwReason 表示 dll 当前所处的状态,例如 DLL_PROCESS_ATTACH 表示 dll 刚刚被加载到
一个进程中,DLL_PROCESS_DETACH 表示 dll 刚刚从一个进程中卸载。当然还有表示加
载到线程中和从线程中卸载的状态,这里省略。最后一个参数是一个保留参数(目前和 dll
的一些状态相关,但是很少使用)。
从上面的程序可以看出,当 dll 被加载到一个进程中时,dll 打印"Dll is attached!"语句;当
dll 从进程中卸载时,打印"Dll is detached!"语句。
编译 dll 需要以下两条命令:
cl /c dll_nolib.cpp
这条命令会将 cpp 编译为 obj 文件,若不使用/c 参数则 cl 还会试图继续将 obj 链接为 exe,
但是这里是一个 dll,没有 main 函数,因此会报错。不要紧,继续使用链接命令。
Link /dll dll_nolib.obj
这条命令会生成 dll_nolib.dll。
注意,因为编译命令比较简单,所以本文不讨论 nmake,有兴趣的可以使用 nmake,或者
写个 bat 批处理来编译链接 dll。
加载 DLL(显式调用)
使用 dll 大体上有两种方式,显式调用和隐式调用。这里首先介绍显式调用。编写一个客户
端程序:dll_nolib_client.cpp
#include <windows.h>
#include <iostream.h>
int main(void)
{
//加载我们的 dll
HINSTANCE hinst=::LoadLibrary("dll_nolib.dll");
if (NULL != hinst)
{
cout<<"dll loaded!"<<endl;
}
return 0;
}
注意,调用 dll 使用 LoadLibrary 函数,它的参数就是 dll 的路径和名称,返回值是 dll 的句
柄。 使用如下命令编译链接客户端:
Cl dll_nolib_client.cpp
并执行 dll_nolib_client.exe,得到如下结果:
Dll is attached!
dll loaded!
Dll is detached!
以上结果表明 dll 已经被客户端加载过。但是这样仅仅能够将 dll 加载到内存,不能找到 dll
中的函数。
使用 dumpbin 命令查看 DLL 中的函数
Dumpbin 命令可以查看一个 dll 中的输出函数符号名,键入如下命令:
Dumpbin –exports dll_nolib.dll
通过查看,发现 dll_nolib.dll 并没有输出任何函数。
如何在 dll 中定义输出函数
总体来说有两种方法,一种是添加一个 def 定义文件,在此文件中定义 dll 中要输出的函数;
第二种是在源代码中待输出的函数前加上__declspec(dllexport)关键字。
Def 文件
首先写一个带有输出函数的 dll,源代码如下:dll_def.cpp
#include <objbase.h>
#include <iostream.h>
void FuncInDll (void)
{
cout<<"FuncInDll is called!"<<endl;
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved)
剩余15页未读,继续阅读
fbi1981
- 粉丝: 0
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论2