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

Reply via email to