2013-06-11 19 views
1

在Windows项目中,我们定义一个接口类DLL导出和虚拟方法

class Interface { 
public: 
    virtual ~Interface() { } 
    virtual void func() = 0; 
}; 

和工厂功能

__declspec(dllexport) Interface *construct(); 

一个DLL里面。当然在DLL里面有一个具体的Interface,但是我们不会导出它。不过,我们可以在DLL之外使用它。这个怎么用?由construct()构造的实例的vftable由函数指针组成,函数指针指向不由DLL导出的函数。这种方法是可以接受的还是或多或少的黑客行为?

回答

3

只是没有任何需要导出具体的类。从接口指针获得的v表将被设置为DLL中存储的具体v表。其中已经有所有的函数指针正确地设置为实现方法。所以一旦你得到了v-表指针,那么你就是金,可以调用任何具体的方法。与COM相比,除了工厂函数(DllGetClassObject)外,您绝不会从COM服务器导出任何内容。

必须导出construct()函数,没有任何其他方式可以获得外部代码的这个函数的地址。需要查找表将函数名称映射到函数地址。 DLL的导出表。导出函数和类将条目添加到该导出表。

+0

所以,如果COM永远不会出口除工厂功能以外的任何东西,它必须是一个被广泛接受的技术。 – phlipsy

+0

而V表的布局来自公共可用的标题,它定义了“接口”? – phlipsy

+0

是的,粗略地说,是编译器根据接口的声明来构建它。一个相当臭名昭着的DLL地狱的来源btw,版本化是困难的。客户端使用接口的新声明并意外加载旧版本的DLL会严重崩溃。 COM要求您在更改界面时始终更改界面IID的核心原因。 –