VC ++链接库(三)非MFC动态库
来源:互联网 发布:centos安装内核开发包 编辑:程序博客网 时间:2024/05/22 06:16
非MFC动态库指的是不用MFC的类库结构,直接用C语言写的DLL,其导出的函数是标准的C接口,能被非MFC或MFC编写的应用程序所调用
在VC++6.0中,File-->New-->Win32 Dynamic-Link Library创建非MFC动态库
(一)一个简单的非MFC动态库
在VC++中new一个Win32 Dynamic-Link Library工程DllTest。注意不要选择MFC AppWizard(dll),因为用MFC AppWizard(dll)建立的将是后面要讲述的MFC 动态链接库。
在建立的工程中添加DllTest.h及DllTest.cpp文件,源代码如下:
//DllTest.h文件#ifdef DLL_API#else#define DLL_API extern "C" _declspec(dllimport) // 需要在每个要导出的函数前面添加标示符 _declspec(dllimport) //用DLL_API代替_declspec(dllimport) //一般添加 extern "C"解决名字改编问题#endifDLL_API int add(int a,int b);DLL_API int subtract(int a,int b);
//DllTest.cpp文件#define DLL_API extern "C" _declspec(dllexport) //这里是_declspec(dllexport) #include "DllTest.h"#include <Windows.h>#include <stdio.h>int add(int a,int b){ return a+b;}int subtract(int a,int b){ return a-b;}直接编译就产生了.lib .dll文件
(二)隐式链接的方式加载DLL
再新建一个工程Test(我们随便建一个win32 console Application),该工程只有一个Test.cpp文件它调用DLL中的函数,代码如下:
#include <stdio.h> #include "..\DllTest\DllTest.h"//#pragma comment( lib, "..\\DllTest\\Debug\\DllTest.lib" ) int main(int argc, char *argv[]) { printf("%d\n",add(5,3)); return 0; }
如何隐式加载,下面我们一步步的分析,
直接build会出错 Test.obj : error LNK2001: unresolved external symbol __imp__add,,有链接的时候出错,解决:在Test程序中,选择Project-->Settings-->ling-->Object/library modules中输入DllTest.lib(或者在程序中加#pragma comment( lib, "..\\DllTest\\Debug\\DllTest.lib" ) ),然后选择tools-->options-->directories-->library files菜单或选项,填入库文件路径E:\Program Files\Microsoft Visual Studio 6.0\MyProjects\DllTest\Debug(或者直接将产生的DllTest.lib文件拷贝到Test工程下),重新build没有问题了。
运行,出错提示计算机中丢失DllTest.dll,那么我们就需要将产生的DllTest.dll文件拷贝到Test工程目录下,重新运行成功
(三)声明导出函数
在刚才的例子中给出的是在函数声明前面加上_declspec(dllimport),同时在前面加上了extern "C"
注:1.编译器在生成DLL时,会对导出的函数进行名字改编,使用不同的编译器分别生成DLL和访问该DLL的客户端程序的话,后者在访问该DLL的导出函数时就会出现问题,所以一般在定义导出函数时,加上限定符extern "C"
2.使用extern "C"可以解决C++和C语言之间互相调用时函数命令的问题,但是不能用于导出一个类的成员函数,只能用于导出全局函数这种情况
3.如果函数的调用约定发生了改变,即使使用了extern "C",它们的名字仍然会发生改变,那么就有了第二周声明导出函数的方式,使用模块文件(DEF)
接着我们将声明导出函数的另外一种方法,使用模块文件
下面我们重新建Win32 Dynamic-Link Library工程DllTest,添加DllTest.cpp文件,代码如下:
int add(int a,int b){ return a+b;}int subtract(int a,int b){ return a-b;}
然后添加模块定义文件DllTest.def,我们可以在DllTest工程目录下新建一个空的文本取名DllTest.def,然后在[Project\Add To Project\Files...]-->Insert Files into Project,选择DllTest.def文件将其添加进Test工程,然后添加代码:
LIBRARY DllTest//LIBRARY指定动态链接库的内部名称,这个必须要和生成的动态链接库名称匹配EXPORTS//指明DLL要导出的函数addsubtractbuild 这个DllTest工程,就产生了.lib .dll文件
自己再编译一个测试工程,代码如下:
#include <stdio.h> #include <windows.h> //typedef int(*lpAddFun)(int, int); // 宏定义函数指针类型int add(int a, int b);int subtract(int a , int b);int main(int argc, char *argv[]) { printf( "%d\n" ,add(5,3)); printf( "%d\n" ,subtract(5,3)); return 0; }
要像刚才隐式加载一样的去做,才能运行成功
(四)显示加载DLL
上面使用的都是隐式加载DLL的方法,对动态链接库的访问还可以使用显示加载方式:完全由编程者用API函数加载和卸载DLL,程序员可以决定 DLL 文件何时加载或不加载,显式链接在运行时决定加载哪个DLL文件
第一步还是创建DllTest工程,产生.lib .dll文件,
第二步新建工程Test(我们随便建一个win32 console Application),代码如下:
//Test.cpp#include <stdio.h>#include <Windows.h>typedef int (*ADDPROC)(int ,int );//定义函数指针类型int main(int argc,char *argv[]){ HINSTANCE hInst; ADDPROC Add; hInst=LoadLibrary("..\\DllTest\\Debug\\DllTest.dll"); //动态加载DLL if(hInst!=NULL) { Add=(ADDPROC)GetProcAddress(hInst,"add");//获取DLL的导出函数 if(Add!=NULL) { int result=Add(5,3); printf("%d\n",result); } FreeLibrary(hInst); } return 0;}
- VC ++链接库(三)非MFC动态库
- VC ++链接库(三)非MFC动态库(后续)
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- VC++动态链接库编程之非MFC DLL
- utf8转gbk,去掉繁体字符
- 杭电 1006
- Android Http请求方法汇总
- Cannot debug project unless a host application is defined
- java发邮件(带附件)
- VC ++链接库(三)非MFC动态库
- 由mysql-安装版 制作 mysql-免安装版
- 杭电 1007
- Jquery Jcrop 插件java的使用方法 包括图片保存类
- 杭电 1008
- 杭电 1009
- 在Win Server2003中SQL2005连接端口1433总是失败
- 杭电 1010
- DSG realsync 表空间映射