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

Posted

技术标签:

【中文标题】在 C++ 中创建 Windows 共享库时如何实现接口隔离【英文标题】:How to implement interface segregation when creating a Windows shared library in C++ 【发布时间】:2018-04-05 09:34:35 【问题描述】:

我在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】:

对于更广泛的范围,您可以查看创建设计模式,但可以给您一些想法的最简单方法是向您的界面添加工厂方法,例如:

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 中被销毁。

【讨论】:

是的,直接使用__dllexport只是为了这个例子。

以上是关于在 C++ 中创建 Windows 共享库时如何实现接口隔离的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows ( C++ ) 中创建进程以运行另一段代码?

如何在 Visual Studio 2017 中创建 C++ Windows 桌面应用程序?

如何在 c++ 中创建一个适用于 Windows 和 linux 的文件夹(目录)[重复]

在 Windows 中创建 C++ 非阻塞计时器

如何从 Windows 控制台调用 .exe (C++) 以在不同目录(或任何目录)中创建文件夹?

如何使用 c++ 和 opengl 在 mac 中创建窗口?