库文件的生成,包孕静态库lib与动态库dll,需要转变编译输出的生成命令,可以一开始生成对应的库工程(或者在工程属性->通例->配置类型变动)。
附根基对报命令:
gcc –c -L
.o
Cl /c /link
.obj
ar
.a
lib
.lib
ld
.o
link
.dll
此中,动态库dll需要在所输出的“东西”前添加_declspec(dllexport)声明。
对付库的使用,除了需要包罗对应的头文件,静态库需要在文件中添加#prama comment(lib,"cof.lib") 或者在有以下几种情况: 1) 不异解决方案下,可在属性面板“框架与引用”添加静态库工程,并”c++”中添加include file即可 2) 在“link”的附加依赖项添加库的目录,在“输入”中使用添加cof.lib(与pragma同)
windows动态库有两种使用方法,使用lib导入库,二是使用window api
1) lib导入库的使用方法与静态库同,但是头文件中的“东西”最好有_declspec(dllimport)声明
2) window api不需要头文件
导出类:
1 简单例子
dllExample.h:
#pragma once
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
extern DLL_API int a;
class DLL_API ExportClass
{
pirvate:
int x;
public:
void foo();
};
dllExample.cpp:
#define DLL_EXPORTS
#include "dllExample.h"
int a = 4;
void ExportClass::foo()
{
//do something...
return;
}
不过这种简单的DLL导出存在一个限制,如果我们导出的类中含有非C++根本类型:
dllExample.h:
#pragma once
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
class DLL_API ExportClass
{
pirvate:
std::string x; //此处的string类型导出是不安适的
public:
void foo();
};
我们知道, 对付STL,微软为每个版本的VS都有差此外实现,VS2008(VC90),VS2010(VC100),VS2013(VC120)。
由于差此外STL的实现,我们不能在差此外版本见直接通报std::string, 否则运行期可能呈现不成预知的错误。
而事实上我们在ExportClass中的std::string x变量是不但愿被外部直接使用的,,也就是并没有export的须要,事实上,不建议让dll向外导出任何关于非C++根本类型的界说。
但是由于ExportClass需要向外导出(因为需要使用foo()函数),应该如何措置惩罚惩罚这样的矛盾呢?
对付这样的问题,我们需要使用C++的抽象类(其实就是java中的interface观点)来解决:
我们需要:
1. 申明一个只有纯虚函数和C++根本类型的基类,所有需要向外部导出的界说都包罗在该类中。
2. 申明另一个类,担任该基类。
3. 实现一个返回基类函数指针的getInstance函数,即返回一个派生类实例的工厂要领。
4. 在外部代码中,通过多态机制访谒该类。
dllExample.h:
#pragma once
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
class DLL_API ExportInterface
{
public:
virtual void foo() = 0;
};
extern "C" DLL_API ExportInterface* getInstance();
#ifdef DLL_EXPORTS //我们并不需要向外导出该类的界说,在外部代码编译时,也不需要包罗此类的界说。
class ExportClass: public ExportInterface
{
pirvate:
std::string x; //由于外部代码对此不偏见,此处的std::string是安适的。
public:
void foo(); //函数体在dllExample.cpp中实现
};
#endif
dllExample.cpp:
#define DLL_EXPORTS
#include "dllExample.h"
extern "C" DLL_API ExportInterface* getInstance()
{
ExportInterface* pInstance = new ExportClass();
return pInstance;
}
void ExportClass::foo()
{
//do something...
return;
}
挪用约定
关于多个库的嵌套:
§ 静态库包罗:静态库或者动态库
只需要对其它库的引用声明为extern即可,库的lib文件不会包罗其它库的具体实现,主要在最终link的应用中包罗其它库。
§ 动态库包罗 :静态、动态库