bogdansrc
bogdansrc

Reputation: 1344

Cocoa check if function exists

I'd like to use a function that's only available on OS X 10.9, but WITHOUT compiling with the 10.9 SDK. Is that possible?

I've tried weak linking, but the compiler just gives out an error that the function is not defined.

Upvotes: 3

Views: 1944

Answers (4)

Vladimir Prudnikov
Vladimir Prudnikov

Reputation: 7242

You should do it like this

if (AXIsProcessTrustedWithOptions != NULL){
    NSDictionary *options = @{(__bridge id)kAXTrustedCheckOptionPrompt: @YES};
    accessibilityEnabled = AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)options);
}else{
    accessibilityEnabled = AXIsProcessTrusted();
}

This method is described in apple's documentation Listing 3-2. It is much simpler than the method described by Richard J. Ross III which you accepted as correct.

Upvotes: 0

Richard J. Ross III
Richard J. Ross III

Reputation: 55563

Assuming you are talking about a C function, you can do this with the dlopen function:

#include <dlfcn.h>

int main() {
    void *lib = dlopen("/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices", RTLD_LAZY);
    void *function = dlsym(lib, "CGColorGetConstantColor");

    // cast the function to the right format
    CGColorRef (*dynamic_getConstantColor)(CFStringRef colorName) = function;

    NSLog(@"%@", dynamic_getConstantColor(CFSTR("kCGColorBlack")));

    dlclose(lib);
}

Output:

2013-06-20 12:43:13.510 TestProj[1699:303]  [ (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Profile)] ( 0 1 )

You will need to figure out the dylib in which the function you want resides, first, though.

This will break the sandbox limitations on iOS, and Mac most likely as well. It is the price you pay for trying to get around the linker.

Upvotes: 3

CRD
CRD

Reputation: 53010

You say you don't want to compile against 10.9, but give no reason. Just in case you can:

If you set your target to 10.9 and your deployment to something lower then Xcode will weak link the 10.9 frameworks. You can then test for a C function being available by comparing its name to NULL. This fragment is taken from this document:

extern int MyWeakLinkedFunction() __attribute__((weak_import));

int main()
{
   int result = 0;

   if (MyWeakLinkedFunction != NULL)
   {
      result = MyWeakLinkedFunction();
   }

   return result;
}

(BTW: no sandbox issues this way.)

Upvotes: 4

lukaswelte
lukaswelte

Reputation: 3001

If you are dealing with Objective-C methods, maybe you could do it with selectors.. So first check if the selector is available with:

[object respondsToSelector:@selector(osxMavericksFun)]

And if this test is correct try firing the Method via selectors

[object performSelector:@selector(osxMavericksFun)];

If you want to call c functions there is no way to do this.

Upvotes: 0

Related Questions