创建编译库文件有个好处就是不容易被修改,加密的,方便调用,但是缺点是不容易查看其中的内容,反编译比较麻烦。下面让我们使用VC创建编译自己的库文件吧。常用的函数,不常更改的,应该放到库文件里,所以库文件的意义非比寻常。但为了(这里需要明白C++库和C++组件(COM组件)、插件、OCX的区别) DLL与COM面试问题 DLL和插件的相关性 插件是使用了某种规则的DLL 给自己的程序添加插件功能dll做插件 DLL插件设计思想 使用DLL作为插件的设计框架 插件开发(Java) 基于插件式的开发框架 插件技术(Android)
dll库中主要是一个函数,当然还有类和变量这些辅助对象,其主要目的是为了实现某个特定的功能,可以由任意程序调用。这跟静态库不同。
dll与lib的区别:lib是在编译时和可执行程序打包到一起的,外部看不到它的存在,它在exe里面,所以如果丢失了dll它依然可以运行。它是静态链接库,是目标对象obj的集合。而dll在导出时,有时没有lib文件,有时有lib文件,而存在的这种lib文件就是导出文件,到出库。这样的lib,导入文件,包含DLL导出的函数和变量的符号名,而真正的函数的实现和数据存在于DLL。lib占用内存,dll只用用时才占用内存。
举个例子:
__declspec(dllexport)
声明一个导出函数,是说这个函数要从本DLL导出。我要给别人用。一般用于dll中省掉在DEF文件中手工定义导出哪些函数的一个方法。当然,如果你的DLL里全是C++的类的话,你无法在DEF里指定导出的函数,只能用__declspec(dllexport)导出类。
__declspec(dllimport)
声明一个导入函数,是说这个函数是从别的DLL导入。我要用。一般用于使用某个dll的exe中不使用__declspec(dllimport)也能正确编译代码,但使用__declspec(dllimport)使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于DLL中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨DLL边界的函数调用中。但是,必须使用__declspec(dllimport)才能导入DLL中使用的变量。
为什么叫导入文件,就是把Dll中导出的函数,类给导入到我们自己的应用程序中使用。
使用方法:1、静态链接库(lib),我们使用隐式链接; 2、动态链接库(DLL),不包含lib导入文件,我们用显式链接。但是这样会很麻烦,我不喜欢这样用,我会想尽方法让它带有lib文件。 3、动态链接库(DLL),包含lib导入文件,我们使用 隐式链接。
1. 新建-->项目-->Win32 Console-->勾选dll-->确定。
2. MyDll.h头文件声明
#ifdef MYDLL_EXPORTS #define MYDLL_API __declspec(dllexport) //定义MYDLL_API为导出类型 #else #define MYDLL_API __declspec(dllimport) #endif // This class is exported from the MyDll.dll 该类从MyDll.dll中导出 class MYDLL_API CMyDll { public: CMyDll(void); CMyDll(int _age, char *_name); //年龄和姓名 构造函数 ~CMyDll(); // TODO: add your methods here. void Introduce(); //介绍函数 static void SayStatic(); private: int age; char* name; static int a; };
extern MYDLL_API int nMyDll;//导出全局变量的声明
extern MYDLL_API float f;
extern MYDLL_API int a;
MYDLL_API int fnMyDll(void); //导出全局函数的声明
MYDLL_API void SayHell();
3. MyDll.cpp文件的函数和类的实现
#include "stdafx.h" #include "MyDll.h" #include <iostream> #include <string.h> #include <algorithm> using namespace std; // This is an example of an exported variable MYDLL_API int nMyDll=0; MYDLL_API float f = 3.14; MYDLL_API int a = 23; int CMyDll::a = 90; //全局变量 // This is an example of an exported function. MYDLL_API int fnMyDll(void) { return 42; } MYDLL_API void SayHell() //全局函数 { cout<<"Hello World!"<<endl; } //静态函数 void CMyDll::SayStatic() { cout<<"我是类中的静态函数"<<endl; cout<<"类中静态变量初始化值是:a="<<CMyDll::a<<endl; } // This is the constructor of a class that has been exported.这是已导出类的构造函数 // see MyDll.h for the class definition有关该类的定义参阅MyDll.h CMyDll::CMyDll():name(NULL) { return; } CMyDll::~CMyDll() { if(name != NULL) { delete[]name; } } CMyDll::CMyDll(int _age, char *_name):age(0), name(NULL) { this->age = _age; if(_name != NULL) { int len = strlen(_name)+1; if(name==NULL) { name = new char[len]; } strcpy_s(name, len, _name); } } void CMyDll::Introduce() { cout<<"My name is yujianhui"<<endl; cout<<"Name:"<<name<<endl; cout<<"Age:"<<age<<endl; }
项目生成如下:
测试:(这里属于静态加载,即lib和dll都存在的情况下)
步骤:1.在程序中添加头文件;2.加载lib;3.使用。
示例:
#include<iostream> #include "MyDll.h" #pragma comment(lib, "MyDll") using namespace std; int main() { cout<<a<<endl; cout<<f<<endl; SayHell(); CMyDll mydll(24, "yujianhui"); mydll.Introduce(); CMyDll::SayStatic(); system("pause"); }
程序下载:http://pan.baidu.com/s/1mhEqfxQ
程序介绍:VS2010版 使用方法:解压后,使用VS打开.sln文件,然后单击Debug->Start Without Debugging就可以看到运行结果了。因为我为了让压缩包变小所以删除了过程文件,会提示你重新编译,单击确定即可。