如何隔离仅允许创建为单例的不良行为 3rd-party c-lib?

Posted

技术标签:

【中文标题】如何隔离仅允许创建为单例的不良行为 3rd-party c-lib?【英文标题】:How to isolate bad behaving 3rd-party c-lib which only allows to be created as singleton? 【发布时间】:2014-02-19 14:19:18 【问题描述】:

目前我正在开发一个原生 C nodejs 插件来包装一个 3rdparty 闭源 c-lib 并将其公开给 nodejs。

到目前为止一切顺利。我的解决方案有效,并且可以调用和使用本机代码。

当随后对这些函数进行调用时,就会出现一个问题。 3rdParty 库似乎总是为其运行时对象分配相同的 struct(?; speak: 内存中的相同位置)。

我能以某种方式“沙盒”这个 3rdparty-lib 吗? 有解决这个问题的模式吗?也许特定于 nodejs-addon 开发,因为 nodejs 是单线程、单进程应用程序。

在这种情况下,一般建议似乎在单独的进程中运行 3rdParty 库,例如此处所述:Isolating and multiply instantiating a C library in-process

除了将自己的 nodejs 进程创建为“worker”并以某种方式通过 rpc 与之通信外,我不太确定如何将此模式适应 nodejs。但这对我来说似乎有点尴尬,我不想重新发明***。

恕我直言,为此而产生不同的节点进程似乎是“最丑陋”的解决方案。 但如果我错了,请纠正我。

长话短说。感谢您的建议。

【问题讨论】:

最好的办法:切换库或欺负提供者使其只有可重入函数;从长远来看,它会好得多。 @MatthieuM。这绝对是最好的,但不幸的是,这不是一个选择。这是一个较旧的(付费)3rdParty 库,已在广泛的其他应用程序中使用。我认为他们不会改变... 【参考方案1】:

这是一个非常非常困难的问题,我找到的唯一解决方案是在一个临时目录(使用不同的名称)中创建共享对象的许多副本,您的程序会在其中加载每个共享对象一次。大多数链接器不会意识到它们是相同的,并允许您将它们加载到不同的地址空间中。但是,这确实依赖于与位置无关的代码,因此可能无法正常工作。它也几乎和使用 IPC 一样难看,所以由你决定。

【讨论】:

如果我没听错,您是在建议通过路径动态加载共享库,对吗?就像这里解释的那样:ehuss.com/shared ?目前我的 3rdParty 库被静态编译/链接到我的 nodejs c 模块中。我必须把它排除在外并动态加载吗? 是的,这正是我要说的,只要每次路径不同,链接器就会加载一个新实例,因此共享对象文件的多个副本将链接在不同的地址空间.有关如何执行此操作的更多信息,请查看此处(有一个具有非常相似界面的等效窗口):man7.org/linux/man-pages/man3/dlopen.3.html 刚刚尝试了这个解决方案......而且......万岁!它有效 :) 很酷的东西 :)

以上是关于如何隔离仅允许创建为单例的不良行为 3rd-party c-lib?的主要内容,如果未能解决你的问题,请参考以下文章

iOS:创建常见的单例 UIView [关闭]

spring小结

设计模式:单例设计模式

如何使用 NestJS 创建充当单例的服务

单例模式(下)特殊单例的实现

Bean的五个作用域