Mixing C functions in an Objective-C class
I am writing an Objective-C class but it uses an API written in C. This is mostly fine as mixing C calls with Objective-C calls causes few problems.
However one of the API call requires a call back method (example):
success = CFHostSetClient(host, MyCFHostClientCallBack, &context);
Where MyCFHostClientCallBack
is a C function defined like this:
static void MyCFHostClientCallBack(CFHostRef host, CFHostInfoType typeInfo, const CFStreamError *error, void *info);
- Can/How do I call an Objective-C method in place of this?
- Can/Should I mix C functions with my Objective-C calls?
- How do I mix C functions with Objective-C methods?
Solution 1:
Mixing C and Objective-C methods and function is possible, here is a simple example that uses the SQLite API within an iPhone App: (course site)
Download the Zip file (09_MySQLiteTableView.zip)
C functions need to be declared outside of the @implementation
in an Objective-C (.m) file.
int MyCFunction(int num, void *data)
{
//code here...
}
@implementation
- (void)MyObjectiveCMethod:(int)number withData:(NSData *)data
{
//code here
}
@end
Because the C function is outside of the @implementation
it cannot call methods like
[self doSomething]
and has no access to ivars.
This can be worked around as long as the call-back function takes a userInfo
or context
type parameter, normally of type void*
. This can be used to send any Objective-C object to the C function.
As in the sample code, this can be manipulated with normal Objective-C operations.
In addition please read this answer: Mixing C functions in an Objective-C class
Solution 2:
To call Objective-C code from a C callback I would use something like:
void * refToSelf;
int cCallback()
{
[refToSelf someMethod:someArg];
}
@implementation SomeClass
- (id) init
{
self = [super init];
refToSelf = self;
}
- (void) someMethod:(int) someArg
{
}
Solution 3:
Can/How do I call an Objective-C method in place of this?
You cannot.
Can/Should I mix C function in with my Objective-C call?
Yes. Write a C function and use that as the callback to the CF function.
How do I mix C function with Objective-C methods?
You can set self
as the info
pointer in your context structure. That will be passed to the callback. Then, in the callback, cast the info
pointer back to id
:
MyClass *self = (id)info;
You can then send self
messages. You still can't directly access instance variables, though, since a C function is outside of the @implementation
section. You'll have to make them properties. You can do this with a class extension. (Contrary to what that document says, you would not declare the extension inside @implementation
, but in the same file with it, generally right above it.)