views:

194

answers:

3

I have an application for Mac OS X that supports plugins that are intended to be loaded at the same time. Some of these plugins are built on top of a Cocoa framework that may receive updates in one plugin but not another. Given Objective-C's current method for function dispatching, any call from any plugin to a given Objective-C routine will go to the same routine every time. That means plugin A can find itself inside plugin B with a trivial Objective-C call! Obviously what we're looking for is for each plugin to interact with its own version of the framework upon which it was built. I have been reading some on Objective-C and this particular need, but haven't found a definitive solution for it yet.

Update: My use of the word "framework" above is misleading: the framework is a statically-linked library, built into the plugin(s) that need it. The way Objective-C handles dispatching, however, even these statically linked pieces of disparate code will co-mingle in the Objective-C dispatcher, leading to unintended consequences.

Update 2: I'm still a bit fuzzy on the answer provided here, as it doesn't seem to propose a solution as much as an unproven hypothesis.

A: 

I don't think I understand you comment about "plugin A can find itself inside plugin B." I'm guessing you mean that once you've loaded some dependent framework once, then everyone will use it rather than loading their own, and that's correct. And that's correct whether you have something like namespaces or not.

This is the same problem you would face if one plugin required one version of OpenSSL, and another plugin required another version of OpenSSL. You can't load two libraries that provide the same symbols.

Do I understand the problem? Various plugins require different, incompatible versions of the same framework? My approach, if possible, would be to change the framework to a static library and statically link your plugins to their framework. If you're not sharing the framework between the plugins, then a framework really isn't what you want. You want to just compile the code (static linking). The whole point of a framework is to share.

Rob Napier
That's the thing -- if the libraries are statically linked you're toast, too; the way Objective-C handles dispatching *everything* gets handled by a single dispatcher, so two completely different, 100% statically-linked plugins can find themselves calling each other's routines inadvertently.
fbrereto
+1  A: 

You can't do that (at least not trivially), Objective-C currently has no notion of namespaces, and the runtime only presents a single (global) dispatch table.

Note that this is not unique to Objective-C, even C based plugins can also call between each other fairly trivially, since everything is in the same address space. Admittedly, if you are worried about accidentally doing it is less likely because of two-level namespaces, but those won't protect you if some plugin explicitly tries to enter another code.

If you really want to isolate plugins you can create separate helper processes where you run code that loads the plugin and have your application perform RPCs between itself and the helper apps. This is what Safari does in 64-bit on Snow Leopard, for instance. There are a number of benefits to this approach, but it is fairly complex to implement and you have to roll most of it yourself.

Louis Gerbarg
A: 

The best solution thus far is a derivative from the idea proposed in this question

fbrereto