开发者

How do I get a bundle reference from inside of a plugin with carbon?

I'm writing a C++ plugin in Mac OS X using the Carbon framework (yeah, yeah, I know, Apple is deprecating Carbon, but at the moment I can't migrate this code to Cocoa). My plugin gets loaded by a master application, and I need to get a CFBundleRef reference to my plugin so that I can access it's resources.

The problem is, when I call CFBundleGetMainBundle() during my plugin's initialization routines, that returns a reference to the host's bundle reference, not the plugin's. How can I get a reference to my plugin's bundle inste开发者_如何学JAVAad?

Note: I would rather not use anything determined at compile-time, including calling CFBundleGetBundleWithIdentifier() with a hard-coded string identifier.


See this posting on the carbon-dev mailing list, which seems to be a similar situation.

The method given there is

I recommend using CFBundleGetBundleWithIdentifier. Your plug-in should have an unique identifier; something like "com.apple.dts.iTunes_plug-in", etc. Look for the CFBundleIdentifier property in your plug-in's bundle's info.plist.


Note: I would rather not use anything determined at compile-time, including calling CFBundleGetBundleWithIdentifier() with a hard-coded string identifier.

Because that's WET, right?

Here's how you can make that solution DRY.

First, define some macros for this in a header file, like so:

#define MY_PLUGIN_BUNDLE_IDENTIFIER com.example.wiflamalator.photoshop-plugin
#define MY_PLUGIN_STRINGIFY(x) #x
#define MY_PLUGIN_BUNDLE_IDENTIFIER_STRING MY_PLUGIN_STRINGIFY(MY_PLUGIN_BUNDLE_IDENTIFIER)

Import the header file into the code that calls CFBundleGetBundleWithIdentifier. In that code, use CFSTR(MY_PLUGIN_BUNDLE_IDENTIFIER_STRING).

Then, in Xcode, either set that file as your Info.plist prefix header, or (if you already have one) #include it into that header. Finally, in Info.plist, set the bundle identifier to MY_PLUGIN_BUNDLE_IDENTIFIER (in a string value, of course).

Now you have the bundle identifier written in exactly one place (the header), from which the C preprocessor puts it in all the places where it needs to be, so you can look up your own bundle by it using CFBundleGetBundleWithIdentifier.


#ifdef __APPLE__
#include "CoreFoundation/CoreFoundation.h"
#endif

#ifdef __APPLE__
    // This should be actually defined somewhere else
    #define MY_PLUGIN_BUNDLE_IDENTIFIER com.yourbundle.name

    // Then all the regular stuff
    #define QUOTE(str) #str
    #define EXPAND_AND_QUOTE(str) QUOTE(str)
    #define MY_PLUGIN_BUNDLE_IDENTIFIER_STRING EXPAND_AND_QUOTE(MY_PLUGIN_BUNDLE_IDENTIFIER)

    CFBundleRef mainBundle = CFBundleGetBundleWithIdentifier(CFSTR(MY_PLUGIN_BUNDLE_IDENTIFIER_STRING));
    CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
    char path[PATH_MAX];
    if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX))
    {
        // error!
    }
    CFRelease(resourcesURL);

    chdir(path);
    StoragePaths::setApplicationResourcesDirectory(STR(path));
#endif

Prints the path to the your bundle

Note: For JUCE users, use JucePlugin_CFBundleIdentifier instead of MY_PLUGIN_BUNDLE_IDENTIFIER and you're all set

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜