On Jul 20, 2010, at 10:36 AM, Nick Ludlam wrote: > On 19 Jul 2010, at 22:00, Laurent Sansonetti wrote: > >> 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. > > Thanks Laurent, > So in my case, do I even need to implement this method? If I understand > correctly, the Init_*() method is used in standard Ruby C extensions, and you > would usually call rb_define_module(), rb_define_method() etc. in order to > make your Ruby class definitions. > > By using NSBundle.bundleWithPath, I'm effectively not using any native Ruby, > as they are direct Foundation calls. Is the definition of > Init_TagLibBundle() only there to satisfy what the #require method demands?
Yes, this is right. If you use NSBundle to load the bundle you do not need to have an Init function. >>> 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 couldn't get #require to work, but that might be to do with the name of the > bundle being 'TagLibBundle.bundle', rather than just 'TagLibBundle'. I need > to investigate. Strange, it should work if you pass a full path to the bundle file, file extension included. >> 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). > > Yes, I'm not sure where it should live, but I don't think it breaks anything > having non-Framework objects in 'Frameworks'. I'd be interested to hear if > there's a consensus amongst MacRubyists here as to what is best practice. > >>> 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). > > Ok that's good to know, thanks. > >>> 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.). > > Yes completely, the tutorial got me all the way to working code, which is > great. I was just unsure of some of the more specific details. > > I want to write up this process of getting id3 tags visible in MacRuby, as > the pure native gem has problems working with 0.6, and this seemed to be the > best route for distribution packaging. I'm hoping this will help others in > showing how you can easily bridge the compiled world with the interpreted > world. That would be interesting :) Let us know once you wrote about it. Laurent _______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel