在 libCall 工程仅包含一个 main.cpp 文件,它演示了静态链接库的调用方法,其
源代码如下: #include
#include "..\lib.h" #pragma comment( lib, "..\\debug\\libTest.lib" ) //指定与静态库一起连接 int main(int argc, char* argv[]) { printf( "2 + 3 = %d", add( 2, 3 ) ); } 静态链接库的调用就是这么简单,或许我们每天都在用,可是我们没有明白这个概念。 代码中#pragma comment( lib , "..\\debug\\libTest.lib" )的意思是指本文件生成的.obj 文件应与 libTest.lib 一起连接。 如果不用#pragma comment 指定,则可以直接在 VC++中设置,如图 2,依次选择 tools、 options、directories、library files 菜单或选项,填入库文件路径。图 2 中加红圈的部分为我们 添加的 libTest.lib 文件的路径。
图 2 在 VC 中设置库文件路径 这个静态链接库的例子至少让我们明白了库函数是怎么回事, 它们是哪来的。 我们现在 有下列模糊认识了: (1)库不是个怪物,编写库的程序和编写一般的程序区别不大,只是库不能单独执行; (2)库提供一些可以给别的程序调用的东东,别的程序要调用它必须以某种方式指明 它要调用之。 以上从静态链接库分析而得到的对库的懵懂概念可以直接引申到动态链接库中, 动态链 接库与静态链接库在编写和调用上的不同体现在库的外部接口定义及调用方式略有差异。 3.库的调试与查看
在具体进入各类 DLL 的详细阐述之前,有必要对库文件的调试与查看方法进行一下介 绍,因为从下一节开始我们将面对大量的例子工程。 由于库文件不能单独执
行,因而在按下 F5(开始 debug 模式执行)或 CTRL+F5(运行) 执行时, 其弹出如图 3 所示的对话框, 要求用户输入可执行文件的路径来启动库函数的执行。 这个时候我们输入要调用该库的 EXE 文件的路径就可以对库进行调试了,其调试技巧与一 般应用工程的调试一样。
图 3 库的调试与“运行” 通常有比上述做法更好的调试途径,那就是将库工程和应用工程(调用库的工程)放置 在同一 VC 工作区,只对应用工程进行调试,在应用工程调用库中函数的语句处设置断点, 执行后按下 F11,这样就单步进入了库中的函数。第 2 节中的 libTest 和 libCall 工程就放在 了同一工作区,其工程结构如图 4 所示。
图 4 把库工程和调用库的工程放入同一工作区进行调试 上述调试方法对静态链接库和动态链接库而言是一致的。 所以本文提供下载的所有源代 码中都包含了库工程和调用库的工程, 这二者都被包含在一个工作区内, 这是笔者提供这种 打包下载的用意所在。 动态链接库中的导出接口可以使用 Visual C++的 Depends 工具进行查看,让我们用 Depends 打开系统目录中的 user32.dll,看到了吧?红圈内的就是几个版本的 MessageBox 了!原来它 真的在这里啊,原来它就在这里啊!
图 5 用 Depends 查看 DLL 当然 Depends 工具也可以显示 DLL 的层次结构,若用它打开一个可执行文件则可以看 出这个可执行文件调用了哪些 DLL。 好,让我们正式进入动态链接库的世界,先来看看最一般的 DLL,即非 MFC DLL(待 续...)
上节给大家介绍了静态链接库与库的调试与查看(动态链接库(DLL)编程深入浅出(一)) ,本 节主要介绍非 MFC DLL。 4.非 MFC DLL 4.1 一个简单的 DLL 第 2 节给出了以静态链接库方式提供 add 函数接口的方法, 接下来我们来看看怎样用动 态链接库实现一个同样功能的 add 函数。 如图 6,在 VC++中 new 一个 Win32 Dynamic-Link Library 工程 dllTest(单击此处下载 本工程附件) 。注意不要选择 MFC AppWizard(dll),因为用 MFC AppWizard(dll)建立的将是 第 5、6 节要讲述的 MFC 动态链接库。
图 6 建立一个非 MFC DLL 在建立的工程中添加 lib.h 及 lib.cpp 文件,源代码如下: /* 文件名:lib.h */ #ifndef LIB_H #define LIB_H extern "C" int __declspec(dllexport)add(in