Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling Cocoa APIs from C

Tags:

c

macos

cocoa

I don't know if this is possible, but having code in plain C, is it possible to call Cocoa API's from it?
Something like #include <cocoa.h>, add the corresponding library and go for it?

Thanks for the help

like image 751
Mr Aleph Avatar asked May 05 '11 17:05

Mr Aleph


People also ask

What is Cocoa Objective C?

Objective-C is the native language of Cocoa applications. It is an object-oriented superset of ANSI C, allowing the developer to include "plain C" statements and code into the program. Any ANSI C program is a valid Objective-C program.

Is cocoa obsolete?

Cocoa powder doesn't spoil so it won't cause you to become ill. Instead, it starts to lose potency over time. Cooks Illustrated conducted a test to determine if cocoa still tasted good months and years after it's considered expired.

Does Apple still use cocoa?

People buy Macs because of the software ecosystem, so keeping the OS (and the programs running on it) high quality is extremely important. So, Apple uses Cocoa for its applications. Not all of them—Apple's bought-in applications generally use Carbon, as well as a few high profile parts of Mac OS X itself.

What language is cocoa from?

Despite having just learnt that cocoa is the English adaptation of the Spanish word cacao, there are subtle differences in the meaning of the two terms that have developed over time.


2 Answers

If you link against the Cocoa or Foundation frameworks, you can use objective-c within your C code. However, if you want to use the normal messaging syntax, you will have to change the file extension from .c to .m so that it is compiled as objective-c. If you keep the .c extension, you will only be able to use the c-style runtime calls to interact with objective-objects (i.e. objc_msgSend, objc_getClass, etc.).

Examples: Within a .m file

void cFunction() {
    [[NSString alloc] init];
}

Within a .c file

void cFunction() {
    void* cls = objc_getClass("NSString");
    void* obj = objc_msgSend(cls, NSSelectorFromString(CFSTR("alloc")));
    obj = objc_msgSend(obj, NSSelectorFromString(CFSTR("init")));
}

If you choose the second method, see the Objective-C Runtime Reference.

like image 103
ughoavgfhw Avatar answered Oct 08 '22 16:10

ughoavgfhw


Objective-C is a very thin wrapper on top of C. The compiler just translates

 [obj message:argument];

into a C-call

 obj_msgSend(obj,@selector(message:),argument);

and that's it (where @selector(message:) is a magic encoding turning a selector (method name) into a computer-understandable-thingy.)

As such, there is not much difference between Objective-C and C from the compiler's viewpoint. For example, you can compile a pure C program with an Objective-C compiler, with exactly the same result as you would get by compiling with a C compiler.

So, the easiest way to "mix" a bit of Objective-C with C is to use .m extension so that the compiler use Objective-C.

That doesn't make your program suddenly very Objective-C-y. You can keep your program almost pure C, with the extension .m. With .m, you can add a few lines of Objective-C message calls without problems.

like image 32
Yuji Avatar answered Oct 08 '22 17:10

Yuji