[MacRuby-devel] Loading bundled bundles; #require or #framework?

Laurent Sansonetti lsansonetti at apple.com
Mon Jul 19 14:00:50 PDT 2010


Hi Nick,

On Jul 18, 2010, at 11:34 AM, Nick Ludlam wrote:

> Hi all,
> sorry for the tongue-twister message subject, but I'm having a difficult time figuring out how #require works, within the context of loading custom Bundles at startup.
> 
> I've been following http://www.macruby.org/recipes/create-an-objective-c-bundle.html and have successfully created an obj-c wrapper around a c++ library in order to read id3 tags from mp3 files.
> 
> My obj-c class is called 'TagLibBundle' and I've implemented the following init method as specified:
> 
>  void Init_TagLibBundle(void) { }

This Init method is only required if you use #require. #require tries to locate and call this function based on the basename of the path given to it. C extensions use this function to create classes and methods. In your case, since the wrapper is all in Objective-C, nothing has to be initialized, so the init function can remain empty.

> So far, so good. I've added the bundle to a MacRuby project, and it's copied into the Frameworks/ folder in the app bundle during the build. I am able to load the bundle with the following statement:
> 
>  bundle_path = NSBundle.mainBundle.privateFrameworksPath
>  NSBundle.bundleWithPath(bundle_path + "/TagLibBundle.bundle").loadAndReturnError(nil)

That should work. If you use NSBundle to load the bundle, then you don't need the Init function as discussed above. Otherwise, you can keep the Init function and you may be able to use #require here. 

I am not sure if the Frameworks directory inside your app bundle is the right place for a bundle (even though it might not matter).

> I can also load the bundle with:
> 
>  bundle_path = NSBundle.mainBundle.privateFrameworksPath
>  framework(bundle_path + '/TagLibBundle.bundle')

This can work too but #framework is supposed to be used against frameworks, not simple bundles. #framework does quite a bit more of logic (like, trying to locate a BridgeSupport file), so it may not be a good idea to use it to load non-framework dynamic libraries (such as simple dylibs or bundles).

> So I have two questions:
> 
> Can I add the privateFrameWorksPath to the #framework search path, like you would with $:.unshift(path), and get rid of the absolute path?

I would recommend using NSBundle or require to load it and calculate the path at runtime like you do already.

> And is the tutorial incorrect in using #require to load the bundle, where it should be #framework? Or have I got something wrong with my setup?

I think the tutorial is good, but it could probably be improved with a discussion around the Init function (why it's needed, etc.).

Laurent


More information about the MacRuby-devel mailing list