如何在C ++中创建Windows共享库时实现接口隔离

时间:2018-04-05 09:34:36

标签: c++ linker

我在C++中实施了一个类。我想创建一个导出该类的共享库,但只能创建某些方法。例如,我想将内部链接应用于所有私人成员。

我已阅读anoymous namespaces可能导致的问题,因此我放弃了该选项。相反,我想尝试使用界面隔离,但我不知道如何在共享库中实现它。让我解释一下:

假设您有以下代码:

// MyLib.h
class MyLib {
public:
   int fun1() { return _i; }
   double fun2() { return _d; }
   bool fun3() { return _b; }

private:
   int _i;
   double _d;
   bool _b;
};

我想创建一个共享库,导出符号MyLib并且只导出其中一个方法,例如fun1

我无法将MyLib标记为dllexport,因为这样会导出所有类'符号,包括私人成员。所以我想创建一个只有一个方法的接口并将其导出:

class __declspec(dllexport)  IMyLib {
   virtual int fun1() = 0;
};

class MyLib : public IMyLib {
   // Same as above...
};

以下帖子解释了此架构:How do I export class functions, but not the entire class in a DLL

现在,我的问题是,我不明白,在使用MyLib.dll的情况下,您如何实例化IMyLib 对象,因为实现它的类是隐藏的(internal linkage),因此您无法从共享库中访问它。

1 个答案:

答案 0 :(得分:0)

对于更广泛的范围,您可以查看创建设计模式,但最简单的方法可以为您提供一些工厂方法,如:

class EXPORTED  IMyLib {
   virtual int fun1() = 0;
   static IMyLib* create();
};

并在DLL中实现它,如:

IMyLib* IMyLib::create()
{
    return new MyLib;
}

您还必须解决删除此类对象的问题。这是您不应使用硬编码指令__declspec(dllexport)的原因之一,而是根据上下文使用dllexportdllimport之间的宏切换。它将有助于选择DLL中定义的权限operator delete。否则,Visual C ++编译器将使用客户端模块中的一个,该模块可能与DLL不兼容。但它仍然可能还不够,因为客户端模块甚至可以用不同的语言编写,所以为了安全添加static void destroy(IMyLib*);它将保证对象在创建它的同一DLL中被销毁。