• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Plugins (was Re: CoreFoundation question)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Plugins (was Re: CoreFoundation question)


  • Subject: Re: Plugins (was Re: CoreFoundation question)
  • From: marquis logan <email@hidden>
  • Date: Wed, 29 Aug 2001 00:26:13 -0400

something i'm trying, which appears to be working cleanly is just dumping all the plug-ins in a known location.
/some/where/myplugins

here's a snip:

CFArrayRef bundleArray;
CFURLRef myPluginDir;
CFPlugInRef plugin;
CFIndex i, count;

myPluginDir = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
CFSTR("/some/where/my/plugins"), kCFURLPOSIXPathStyle, TRUE);
bundleArray = CFBundleCreateBundlesFromDirectory(kCFAllocatorDefault,
myPluginDir, NULL);

count = CFArrayGetCount(bundleArray);
for(i = 0; i < count; i++)
{
plugin = CFBundleGetPlugIn((CFBundleRef)CFArrayGetValueAtIndex(bundleArray, i));
if(!plugin)
continue;

// See if this plug-in implements the Test type.
factories = CFPlugInFindFactoriesForPlugInTypeInPlugIn(kMyTypeID, plugin);
<snip>
}

from there you can pretty much follow the example code apple has, which is mostly correct with a few typos.
i just made the _assumption_ that cf would return NULL if a bundle was not a plug-in (and not abort), the documentation doesn't specify (there is no documentation), and for now things work.

nibs

On Tuesday, August 28, 2001, at 04:57 PM, Greg Titus wrote:

On Tuesday, August 28, 2001, at 11:01 AM, email@hidden wrote:
I know it's OT, but I wonder if anyone here can help...
[...]
I think that most folks who use a plug-in architecture (well, me, anyway) want to define one or more types, then be able to dynamically figure out what plugins provide factories for the type(s), without having to have prior knowledge of how the plugins will be named. Am I smoking crack here? So, does anyone know of a way to have the plugin host dynamically locate candidate plugins?

An approach comes to my mind, but before I go down that path, has anyone got some good suggestions?

The app could define a location (or some locations), say, /Library/PlugIns and ~/Library/PlugIns, and enumerate all .plugin packages found in those locations, instantiate the plugins, and then look for factories for the types.

My conceptual problem with the approach is that every plugin-host app must either provide its own subfolder in .../PlugIns (or somewhere else), or else it will be instantiating CFPlugIns for plugins that belong to unrelated apps, and no limiting (until memory is exhausted) how many that might be.

I could find no information from Apple how they recommend partitioning the plugin store.

The other concern that comes to my mind is that it seems not unlikely that tools like web browsers and media players might share some plugin types... so that it becomes preferable in that case to have all plugins centrally located again, without special subdirectories for each one.

Has someone got a pointer to better Apple documentation? I've studied http://developer.apple.com/techpubs/macosx/CoreFoundation/PluginServices/
* pretty thoroughly.

I don't think Apple has anything more specific on this topic. I can tell you what the structure we use looks like, and that may give you some ideas...

As you describe above, OmniWeb looks in /Library/PlugIns, ~/Library/PlugIns, and /Network/Library/PlugIns for .plugin packages. But instead of instantiating all of them, we load the Info.plist inside as a dictionary and look for a couple custom keys.

The first is "OFRequiredSoftwareVersions" which is a dictionary of keys (framework or application names) with the value being a version string. If the .plugin is missing the "OFRequiredSoftwareVersions" key it obviously isn't meant for us, so we discard it and never attempt to load it. Otherwise we match each element in the dictionary with our app name or the names of frameworks which the app loads. If the plugin is meant for a different application, it will contain a key that doesn't match our app or framework list and again, it is discarded and never loaded. Similarly, if the version string doesn't match, the plugin is out of date and discarded.

Notice that we check not only against the app name but against the loaded frameworks. Most of our plugins specify only framework names in the OFRequiredSoftwareVersions section, which means they can be loaded by more than one application as long as each one uses the required framework(s). For instance, our imaging framework has a plugin architecture for parsing and displaying images in different formats (we can't just use the AppKit directly because we want incremental display and animations). The gif.plugin, jpeg.plugin, png.plugin, et cetera can not only be loaded into OmniWeb, but also any other app (say a simple image viewer) that included the framework with the architecture that the plugins are based on.

The second key is "OFRegistrations" which is a series of dictionaries describing what the plugin is actually for. The plugin examination code basically forwards appropriate chunks of the registration dictionary to the classes that might load plugins and they can either decide to load that particular plugin immediately, or store the registration dictionary and plugin location for later. To use the image plugins as an example again, their registration dictionaries specify that they can transform MIME types like "image/gif" or "image/jpeg" or whatever into an image object. This registration information is stored and the plugin isn't actually loaded until the first time the application comes upon some "image/gif" content that needs to be dealt with. It's only at that point that the plugin is loaded and instantiated.

This is all public code, though like all our other code, not well documented. OFBundleRegistry and OFBundledClass in the OmniFoundation framework. It's completely generic and should be useful for any kind of plugin-based Cocoa application.

Also, as another place to look, you may want to check out Apple's documentation on IOKit. It has a somewhat similar approach to describing dependencies and connections in an info dictionary and only loading driver bundles as needed. It's a little more complex because it handles full dependency graphs instead of the simpler two level dependencies (plugin on framework or app) that we manage.

Hope this helps,
--Greg
_______________________________________________
cocoa-dev mailing list
email@hidden
http://www.lists.apple.com/mailman/listinfo/cocoa-dev


  • Follow-Ups:
    • Re: Plugins (was Re: CoreFoundation question)
      • From: Douglas Davidson <email@hidden>
    • Re: Plugins (was Re: CoreFoundation question)
      • From: marquis logan <email@hidden>
References: 
 >Plugins (was Re: CoreFoundation question) (From: Greg Titus <email@hidden>)

  • Prev by Date: Re: (no subject)
  • Next by Date: Re: Plugins (was Re: CoreFoundation question)
  • Previous by thread: Plugins (was Re: CoreFoundation question)
  • Next by thread: Re: Plugins (was Re: CoreFoundation question)
  • Index(es):
    • Date
    • Thread