0

我有一个适用于 Mac OS X 的应用程序,它支持打算同时加载的插件。其中一些插件构建在 Cocoa 框架之上,该框架可能会在一个插件中接收更新,但不会在另一个插件中接收更新。鉴于 Objective-C 当前的函数调度方法,任何插件对给定 Objective-C 例程的任何调用每次都将转到同一个例程。这意味着插件 A 可以通过一个简单的 Objective-C 调用在插件 B 中找到自己!显然,我们正在寻找的是让每个插件与它自己构建的框架版本进行交互。 一直 阅读有关 Objective-C 和这种特殊需求的一些内容,但还没有找到明确的解决方案。

更新:我对上面“框架”一词的使用具有误导性:框架是一个静态链接库,内置在需要它的插件中。然而,Objective-C 处理调度的方式,即使是这些静态链接的不同代码片段也会在 Objective-C 调度程序中混合在一起,从而导致意想不到的后果。

更新 2:我对此处提供的答案仍然有些模糊,因为它似乎没有像未经证实的假设那样提出解决方案。

4

3 回答 3

1

你不能这样做(至少不是微不足道的),Objective-C 目前没有命名空间的概念,运行时只提供一个(全局)调度表。

请注意,这并不是 Objective-C 独有的,即使是基于 C 的插件也可以相当简单地相互调用,因为一切都在同一个地址空间中。诚然,如果您担心意外这样做的可能性较小,因为有两级命名空间,但如果某些插件显式尝试输入另一个代码,这些不会保护您。

如果您真的想隔离插件,您可以创建单独的帮助程序进程,您可以在其中运行加载插件的代码并让您的应用程序在自身和帮助程序应用程序之间执行 RPC。例如,这就是 Safari 在 Snow Leopard 上以 64 位执行的操作。这种方法有很多好处,但实施起来相当复杂,而且您必须自己完成大部分工作。

于 2009-09-24T23:38:51.520 回答
0

我不认为我理解您对“插件 A 可以在插件 B 中找到自己”的评论。我猜你的意思是一旦你加载了一些依赖框架,那么每个人都会使用它而不是加载他们自己的,这是正确的。无论您是否有命名空间之类的东西,这都是正确的。

如果一个插件需要一个版本的 OpenSSL,而另一个插件需要另一个版本的 OpenSSL,这与您将面临的问题相同。您不能加载两个提供相同符号的库。

我明白这个问题吗?各种插件需要同一框架的不同、不兼容的版本?如果可能的话,我的方法是将框架更改为静态库并将插件静态链接到它们的框架。如果您没有在插件之间共享框架,那么框架确实不是您想要的。您只想编译代码(静态链接)。框架的全部意义在于分享。

于 2009-09-24T23:34:31.170 回答
0

迄今为止最好的解决方案是从这个问题中提出的想法衍生而来

于 2010-04-14T22:27:37.260 回答