概要
设想这样一个场景:我有一个类FunClass
,它的声明位于FunClass.h
,并且在FunClass.h
中,我还引用了secret.h
.
现在我需要把FunClass
导出成DLL文件供别人二次开发. 这时我需要给别人以下文件:
FunClass.h
FunClass.lib
FunClass.dll
secret.h
然而我并不想把secret.h
给别人!这个问题可以用一个虚类Fun
(名字瞎起的,不重要,Java的风格是IFunClass
,然而我们是C++) 来解决。
一个简单的例子
假设我的FunClass
有一个方法void A()
,和一个依赖secret.h
的成员Secret M
。那么虚类应当这样写(请为这个虚类新建一个头文件):
////////////////////
//// fun.h
////////////////////
// 请在导出DLL的工程里加上 FUN_EXPORT 预编译指令
#ifndef FUN_EXPORT
#define FUN_API __declspec(dllexport)
#else
#define FUN_API __declspec(dllimport)
#endif
// #include something else
// 注意头文件中没有包含 secret.h
class FUN_API Fun{
public:
Fun(){};
virtual ~Fun(){};
virtual A() = 0;
// 注意这里没有定义 Secret M
}
FUN_API Fun* createFun();
然后Fun
的实现写在Fun.cpp
中:
////////////////////
//// fun.cpp
////////////////////
#include "Fun.h"
#include "secret.h"
// #include something else
// FunClass 继承自 Fun
class FunClass : public Fun{
public:
FunClass(){};
virtual ~Fun(){};
virtual A();
private:
secret M;
}
Fun* createFun(){
return new FunClass();
};
void FunClass::A(){
// A的实现
}
好了!这样就OK了!编译之后会得到Fun.lib
和Fun.dll
,再加上Fun.h
,只需要这三个文件,就能把DLL文件用在其他工程了,下面这段代码是测试:
////////////////////
//// test.cpp
////////////////////
#include "Fun.h"
int main(){
Fun* fun = createFun(); // 虽然看起来比较奇怪,但是为了隐藏 secret.h ,忍了!
fun->A(); // fun 指向一个[FunClass类的实例](用F替代吧),
delete fun; // 由于Fun的析构函数是虚函数,所以fun在析构时会自动调用F的析构函数。
}
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。