精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
服务方向
联系方式
近期使用一个C++MFC开源项目,里面用DLL的方法比较特征,方法在下节讲,本节讲DLL的基础。
动态链接库不能直接运行也不能接收消息,它们是能够被可执行程序或其它dll调用来完成某项工作的函数。我们可以把完成某项功能的函数放在一个动态链接库中,提供给其它人或自己的其它程序使用。
静态库作为一个二进制文件,在编译链接可执行文件的时候,静态库与其它模快一起生成最终可执行文件(.exe),发布产品只需要发布可执行文件就OK了, 而使用动态库的时候,有两个文件,一个引入库(.lib),和我们的dll,这是咋回事,动态库里咋还包含静态库?你别误会,我们引入库跟静态链接库有本质区别,引入库是包含着我们dll导出的函数和变量的符号名,而dll文件包含实际的函数和数据。不过引入库跟静态库一样会跟其它文件一起生成可执行文件,多余的dll需要我们发布产品的时候不仅要发布可执行文件,还要发布dll文件
创建的话我们的开发工具vs就有创建动态库的选项,以前一直不知道这个选项存在的意义,现在知道了。创建后我们创建个.cpp文件,里面写一些方法,构建就可以生成我们的dll文件, 但是这样别人就可以用我们的文件了吗,非也,这时我们还没有导出,函数头加_declspec(dllexport)就可以导出我们的函数让别人使用,同时这时候构建项目不仅生成dll文件,还有lib文件
如何用到这两个函数呢?肯定得声明,同时因为是外部调用的,因此还要加extern,但是这样就可以使用了吗,想想声明是声明了,我们的程序运行的时候去哪里找呢,所以还需要我们的lib文件,lib文件放我们程序所在目录下并在工程设置菜单下选择link,在Object/library module选线框输入我们的lib名字加后缀。但这样就一定能找到我们要调用的函数了吗,如果我们把dll放到另一台电脑上,那想想肯定是调用不到的,它是按什么顺序搜索到我们的动态链接库呢,依次是程序执行目录->当前目录->系统目录->path环境变量目录,因此我们需要根据情况将我们的dll放在合适的目录
完善
看样子这样我们就可以定义并且使用dll了,但是我们自己使用的话我们是知道我们都定义了哪些函数,但是如果我们的dll给别人用,别人怎么知道呢,关键就是我们的头文件,定义一个头文件,不仅可以用来注明各种函数的含义,并且别人用到的时候直接包含我们的头文件就省去了声明各个函数的功夫
一般是用导入形式写MFC和DLL对应的类,但也可以用LoadLibrary来动态构建类, 这个项目里用LoadLibrary,用到了函数指针成员,比较特殊。
头文件里函数指针成员:
HDRAWING (*drwCreate)( );
源文件里初始化函数指针成员:
result = true;
// Construction & Destruction
result &= ((drwCreate = (HDRAWING(*)())
GetProcAddress( hinstCadIO, "drwCreate" )) != NULL);
构造函数里LoadLibrary:
hinstCadIO = LoadLibrary( "CadIO.dll" );
if( !hinstCadIO )
{
// Cannot load CadIO.dll
isLibraryLoaded = false;
return;
}
有了函数指针成员,则再写类的成员函数,成员函数里调用函数指针,这样就封闭了DLL内函数的调用。