Re: NSBundle question
Re: NSBundle question
- Subject: Re: NSBundle question
- From: Douglas Davidson <email@hidden>
- Date: Mon, 10 Dec 2001 10:28:08 -0800
On Friday, December 7, 2001, at 10:51 PM, Bill Bumgarner wrote:
For Mach-O files-- I believe NSBundle only loads Mach-O's?-- one can
use the NSModule API to grab a pointer to C functions. See the man
page for NSModule; in particular the various NSLookup* functions. I
believe NSLookupAndBindSymbol() will do what you want once the NSBundle
has been loaded -- you can force loading of the NSBundle by invoking
the -load method, checking the return type to see if it loaded
successfully.
Once you find the NSSymbol that you are looking for,
NSAddressOfSymbol() will turn it into an address and you can go from
there.
There is actually some more specific dyld API that will allow you, for
example, to look up a symbol in a specific image rather than globally;
and there are quite a few options available. There have been
significant changes with the move to two-level namespaces, and those who
are interested should read through the dyld man pages.
However, most people will find it more convenient to use CFBundle's
CFBundleGetFunctionPointerForName() et al. for their symbol-lookup
needs. I believe the original question on this thread was asking for
the NSBundle equivalent to this CFBundle functionality. The answer to
that is that NSBundle covers most of the relevant CFBundle functionality
(and will cover more in the future), but this particular CFBundle API is
not deemed particularly relevant to NSBundle--since most NSBundle-based
interfaces will use the Objective-C runtime rather than looking up C
entry points by name.
However, if you do find it necessary to look up an exported C function
by name in your NSBundle, it is perfectly kosher to get your bundle's
path, convert it to a URL, create a CFBundle for that, and use
CFBundleGetFunctionPointerForName(). The same goes for any CFBundle
functionality that for some reason you don't find covered in NSBundle.
NSBundle and CFBundle are not toll-free bridged, but an NSBundle and a
CFBundle created pointing to the same bundle on the disk do refer to the
same underlying object, and they are appropriately uniqued so that you
will not get extra instances floating around.
Neither NSBundle nor CFBundle know anything about C++ name-mangling, so
if you are working in C++ you will probably want to declare as extern
"C" any symbol that you wish to look up by name.
There may be API in the core foundation that covers some of this? I'm
not sure-- I do know that there is a plug in architecture over in the
Carbon world that may come into play if you are dyna-loading CFM
binaries, but I don't think it is applicable to mach-o.
Those who are looking to build a C-based plugin architecture have
several choices. The simplest is just to use CFBundle and look up entry
points by name. For those who want more in the way of management, there
is CFPlugIn, which manages interfaces that are passed along as tables of
function pointers. Either CFBundle or CFPlugIn may be used with either
Mach-o or CFM executables, and CFBundle allows a host of one flavor to
work transparently with a plugin of the other; there would be some extra
work involved in doing the same with CFPlugIn.
For those who are working in Objective-C, it is usually much more
convenient to use the Objective-C runtime for this sort of thing. We
recommend that bundles containing Objective-C or Java be loaded using
NSBundle rather than CFBundle, but there should be no problem with using
CFBundle for operations that do not involve loading code, or for using
CFBundle to look up functions by name after the bundle has been loaded
with NSBundle.
Douglas Davidson