在 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)
的原因之一,而是根据上下文在dllexport
和dllimport
之间使用宏切换。这将有助于选择 DLL 中定义的正确 operator delete
。否则,Visual C++ 编译器将使用可能与 DLL 不兼容的客户端模块中的一个。但这可能还不够,因为客户端模块甚至可以用不同的语言编写,所以为了安全起见还要添加static void destroy(IMyLib*);
这将保证对象在创建它的同一个 DLL 中被销毁。
【讨论】:
是的,直接使用__dllexport
只是为了这个例子。以上是关于在 C++ 中创建 Windows 共享库时如何实现接口隔离的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Windows ( C++ ) 中创建进程以运行另一段代码?
如何在 Visual Studio 2017 中创建 C++ Windows 桌面应用程序?
如何在 c++ 中创建一个适用于 Windows 和 linux 的文件夹(目录)[重复]