Search code examples
c++cmacosmacos-carboncore-foundation

How to find CFBundleRef from a function address or a class


Is it possible to get the Bundle reference (CFBundleRef) from a function address or a class name in Carbon..??

I know there are functions in Objective-C

NSBundle myBundle = [NSBundle bundleForClass:(Class)<SOME_CLASS>];

and with Windows API

GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)<SOME_FUNCTION>, &outModule);

Is there anything similar or any other method with C++ on a mac??

Thanks, Abhinay.


Solution

  • You can use the Core Foundation functions that operate on CFBundle to get the bundle reference to the bundle that exports a given function name:

    CFStringRef functionName = CFSTR("someFunctionName");
    CFArrayRef allBundles = CFBundleGetAllBundles();
    CFIndex i;
    CFIndex bundleCount = CFArrayGetCount(allBundles);
    
    for (i = 0; i < bundleCount; i++) {
        CFBundleRef bundle = CFArrayGetValueAtIndex(allBundles, i);
        void *functionPointer = CFBundleGetFunctionPointerForName(bundle, functionName);
        if (functionPointer != NULL) {
            // bundle points to a bundle that exports functionName
        }
    }
    

    And since CFBundleGetDataPointerForName() returns a data pointer to a given symbol name in a bundle, I believe it can be used for class names as well since a class is exported with a symbol name _OBJC_CLASS_$_<className>, e.g. _OBJC_CLASS_$_NSArray.

    As far as I can tell, there’s no function that allows to you to inspect whether a bundle exports a function by specifying the function address.