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?
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
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
{
}
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.)
What I've always found helpful in this situation is to make an Obj-C wrapper on top of the C API. Implement what you need to using C functions, and build an Objective-C class (or two) on top of it, so that's all the outside world will see. For example, in the case of a callback like this, you might make a C function that calls Obj-C delegate methods on other objects.
.m call function inside .c:
CrifanLib.h
#ifndef CrifanLib_h
#define CrifanLib_h
#include <stdio.h>
void fileModeToStr(mode_t mode, char * modeStrBuf);
#endif /* CrifanLib_h */
CrifanLib.c
#include "CrifanLib.h"
#include <stdbool.h>
void fileModeToStr(mode_t mode, char * modeStrBuf) {
// buf must have at least 10 bytes
const char chars[] = "rwxrwxrwx";
for (size_t i = 0; i < 9; i++) {
// buf[i] = (mode & (1 << (8-i))) ? chars[i] : '-';
bool hasSetCurBit = mode & (1 << (8-i));
modeStrBuf[i] = hasSetCurBit ? chars[i] : '-';
}
modeStrBuf[9] = '\0';
}
called by Objective-C's .m:
#include “CrifanLib.h"
#interface JailbreakDetectionViewController ()
#end
#implementation JailbreakDetectionViewController
…
char* statToStr(struct stat* statInfo){
char stModeStr[10];
fileModeToStr(statInfo->st_mode, stModeStr);
...
}
...
done.
Related
I'm new at C, so sorry for my lack of knowledge (my C-book here is really massive :)
I would like to extend a shared library (libcustomer.so) with closed source, but public known api.
Is something like this possible?
rename libcustomer.so to liboldcustomer.so
create an extended shared library libcustomer.so (so others implicitly use the extended one)
link liboldcustomer.so into my extended libcustomer.so via -loldcustomer
forward any not extra-implemented methods directly to the old "liboldcustomer.so"
I don't think it would work that way (the name is compiled into the .so, isn't it?).
But what's the alternative?
For #4: is there a general way to do this, or do I have to write a method named like the old one and forward the call (how?)?
Because the original libcustomer.so (=liboldcustomer.so) can change from time to time, all that stuff should work dynamically.
For security reasons, our system has no LD_PRELOAD (otherwise I would take that :( ).
Think about extended validation-checks & some better NPE-handlings.
Thanks in advance for your help!
EDIT:
I'm just implementing my extension as shown in the answer, but I have one unhandled case at the moment:
How can I "proxy" the structs from the extended library?
For example I have this:
customer.h:
struct customer;
customer.c:
struct customer {
int children:1;
int age;
struct house *house_config;
};
Now, in my customer-extension.c I am writing all the public methods form customer.c, but how do I "pass-thru" the structs?
Many thanks for your time & help!
So you have OldLib with
void func1();
int func2();
... etc
The step 4 might look like creating another library with some static initialization.
Create NewLib with contents:
void your_func1();
void (*old_func1_ptr)() = NULL;
int (*old_func2_ptr)() = NULL;
void func1()
{
// in case you don't have static initializers, implement lazy loading
if(!old_func1_ptr)
{
void* lib = dlopen("OldLibFileName.so", RTLD_NOW);
old_func1_ptr = dlsym(lib, "func1");
}
old_func1_ptr();
}
int func2()
{
return old_func2_ptr();
}
// gcc extension, static initializer - will be called on .so's load
// If this is not supported, then you should call this function
// manually after loading the NewLib.so in your program.
// If the user of OldLib.so is not _your_ program,
// then implement lazy-loading in func1, func2 etc. - check function pointers for being NULL
// and do the dlopen/dlsym calls there.
__attribute__((constructor))
void static_global_init()
{
// use dlfcn.h
void* lib = dlopen("OldLibFileName.so", RTLD_NOW);
old_func1_ptr = dlsym(lib, "func1");
...
}
The static_global_init and all the func_ptr's can be autogenerated if you have some description of the old API. After the NewLib is created, you certainly can replace the OldLib.
I'm trying to call an objective-C function from a C function but the code keeps crashing in objc_msgSend.
My objective-C class is a singleton and I'm using the following code.
void c_function(int arg0, const char *arg1)
{
[[objc_class instance] testFunction:arg0 Arg1:arg1];
}
The gdb shows the crash is happening when objective-C function is being invoked. How cal I call an objective-C function from within a c function?
Thanks
There's nothing wrong with your code as there are no special rules for calling objc methods from c functions. If there is a crash in objc_msgSend, then refer to http://www.sealiesoftware.com/blog/archive/2008/09/22/objc_explain_So_you_crashed_in_objc_msgSend.html. The same thing would have happened if the objc line was in other objc code -- it's likely you forgot to retain the shared instance of your singleton.
[[objc_class instance] testFunction:arg0 Arg1:arg1];
As you don’t provide further information:
objec_class is an instance, your singleton? And it handles the message instance? …
or
objec_class is really a class, having a class method instance? And this will give you another instance …
In other words, do you really have something like
#interface class2 {
}
-(void) testFunction:(int)count Arg1:(const char *)args;
#end
and
#include "class2.h"
#interface objc_class {
}
-(class2*) instance {
}
-(void) testFunction:(int)count Arg1:(const char *)args;
#end
or
#include "class2.h"
#interface objc_class {
}
+(class2*) instance;
// be aware of the fact, instance (normaly) does not have
// access to any instance variables!
to be included?
Your code doesn’t look like „hey, object(instance) singleton, I tell you to ‘instance’. Then I take your response and give it the message ‘testFunction:Arg1:’ (with some values inserted)”!
(Are you sure you understood objective c?)
Greetings
1:
#interface class2 {
}
-(void) testFunction:(int)count Arg1:(const char *)args;
#end
2:
#include "class2.h"
#interface objc_class {
}
-(class2*) instance;
#end
3:
#include "class2.h"
#interface objc_class {
}
+(class2*) instance; // be aware of the fact, instance (normally) does not
// have access to any instance variables!
Is there an mechanism or trick to run a function when a program loads?
What I'm trying to achieve...
void foo(void)
{
}
register_function(foo);
but obviously register_function won't run.
so a trick in C++ is to use initialization to make a function run
something like
int throwaway = register_function(foo);
but that doesn't work in C. So I'm looking for a way around this using standard C (nothing platform / compiler specific )
If you are using GCC, you can do this with a constructor function attribute, eg:
#include <stdio.h>
void foo() __attribute__((constructor));
void foo() {
printf("Hello, world!\n");
}
int main() { return 0; }
There is no portable way to do this in C, however.
If you don't mind messing with your build system, though, you have more options. For example, you can:
#define CONSTRUCTOR_METHOD(methodname) /* null definition */
CONSTRUCTOR_METHOD(foo)
Now write a build script to search for instances of CONSTRUCTOR_METHOD, and paste a sequence of calls to them into a function in a generated .c file. Invoke the generated function at the start of main().
Standard C does not support such an operation. If you don't wish to use compiler specific features to do this, then your next best bet might be to create a global static flag that is initialized to false. Then whenever someone invokes one of your operations that require the function pointer to be registered, you check that flag. If it is false you register the function then set the flag to true. Subsequent calls then won't have to perform the registration. This is similar to the lazy instantiation used in the OO Singleton design pattern.
There is no standard way of doing this although gcc provides a constructor attribute for functions.
The usual way of ensuring some pre-setup has been done (other than a simple variable initialization to a compile time value) is to make sure that all functions requiring that pre-setup. In other words, something like:
static int initialized = 0;
static int x;
int returnX (void) {
if (!initialized) {
x = complicatedFunction();
initialized = 1;
}
return x;
}
This is best done in a separate library since it insulates you from the implementation.
I was reading up about bypassing objective-c's messaging to gain performance (irrelevant to this specific question) when i found an interesting bit of code:
#import <Cocoa/Cocoa.h>
#interface Fib : NSObject { }
- (long long) cFib: (NSUInteger) number;
#end
#implementation Fib
// c implementation of fib
long long cFibIMP(NSUInteger number)
{
return (number < 3) ? 1 : cFib(number - 1) + cFib(number - 2);
}
// method wrapper for c implementation of fib
- (long long) cFib: (NSUInteger) number
{
return cFibIMP(number);
}
#end
My question is; when using c function, within an objective-c object, what scope is the c function (cFibIMP in this particular case) placed in? Does the objective-c class encapsulate the c function removing change of name-clash or is the c function simply dumped into the global scope of the whole objective-c program?
The functions are dumped in the "global" scope.
You can check this by adding a new class at the end of your sample code:
#interface Gib : NSObject {}
#end
#implementation Gib
- (void) t
{
NSLog(#"%d", cFibIMP(10));
}
#end
The C function has global scope.
If you want to have something like "class" scope, your best bet is probably to use the static keyword, which limits the scope of the function to the source file in which it is contained. For the sort of usage you're illustrating here, that's usually close enough.
What's the best way to create a singleton in C? A concurrent solution would be nice.
I am aware that C isn't the first language you would use for a singleton.
First, C is not suitable for OO programming. You'd be fighting all the way if you do. Secondly, singletons are just static variables with some encapsulation. So you can use a static global variable. However, global variables typically have far too many ills associated with them. You could otherwise use a function local static variable, like this:
int *SingletonInt() {
static int instance = 42;
return &instance;
}
or a smarter macro:
#define SINGLETON(t, inst, init) t* Singleton_##t() { \
static t inst = init; \
return &inst; \
}
#include <stdio.h>
/* actual definition */
SINGLETON(float, finst, 4.2);
int main() {
printf("%f\n", *(Singleton_float()));
return 0;
}
And finally, remember, that singletons are mostly abused. It is difficult to get them right, especially under multi-threaded environments...
You don't need to. C already has global variables, so you don't need a work-around to simulate them.
It's the same as the C++ version pretty much. Just have a function that returns an instance pointer. It can be a static variable inside the function. Wrap the function body with a critical section or pthread mutex, depending on platform.
#include <stdlib.h>
struct A
{
int a;
int b;
};
struct A* getObject()
{
static struct A *instance = NULL;
// do lock here
if(instance == NULL)
{
instance = malloc(sizeof(*instance));
instance->a = 1;
instance->b = 2;
}
// do unlock
return instance;
};
Note that you'd need a function to free up the singleton too. Especially if it grabs any system resources that aren't automatically released on process exit.
EDIT: My answer presumes the singleton you are creating is somewhat complex and has a multi-step creation process. If it's just static data, go with a global like others have suggested.
A singleton in C will be very weird . . . I've never seen an example of "object oriented C" that looked particularly elegant. If possible, consider using C++. C++ allows you to pick and choose which features you want to use, and many people just use it as a "better C".
Below is a pretty typical pattern for lock-free one-time initialization. The InterlockCompareExchangePtr atomically swaps in the new value if the previous is null. This protects if multiple threads try to create the singleton at the same time, only one will win. The others will delete their newly created object.
MyObj* g_singleton; // MyObj is some struct.
MyObj* GetMyObj()
{
MyObj* singleton;
if (g_singleton == NULL)
{
singleton = CreateNewObj();
// Only swap if the existing value is null. If not on Windows,
// use whatever compare and swap your platform provides.
if (InterlockCompareExchangePtr(&g_singleton, singleton, NULL) != NULL)
{
DeleteObj(singleton);
}
}
return g_singleton;
}
DoSomethingWithSingleton(GetMyObj());
Here's another perspective: every file in a C program is effectively a singleton class that is auto instantiated at runtime and cannot be subclassed.
Global static variables are your private class members.
Global non static are public (just declare them using extern in some header file).
Static functions are private methods
Non-static functions are the public ones.
Give everything a proper prefix and now you can use my_singleton_method() in lieu of my_singleton.method().
If your singleton is complex you can write a generate_singleton() method to initialize it before use, but then you need to make sure all the other public methods check if it was called and error out if not.
I think this solution might be the simplest and best for most use cases...
In this example, I am creating a single instance global dispatch queue, which you'd definitely do, say, if you were tracking dispatch source events from multiple objects; in that case, every object listening to the queue for events could be notified when a new task is added to the queue. Once the global queue is set (via queue_ref()), it can be referenced with the queue variable in any file in which the header file is included (examples are provided below).
In one of my implementations, I called queue_ref() in AppDelegate.m (main.c would work, too). That way, queue will be initialized before any other calling object attempts to access it. In the remaining objects, I simply called queue. Returning a value from a variable is much faster than calling a function, and then checking the value of the variable before returning it.
In GlobalQueue.h:
#ifndef GlobalQueue_h
#define GlobalQueue_h
#include <stdio.h>
#include <dispatch/dispatch.h>
extern dispatch_queue_t queue;
extern dispatch_queue_t queue_ref(void);
#endif /* GlobalQueue_h */
In GlobalQueue.c:
#include "GlobalQueue.h"
dispatch_queue_t queue;
dispatch_queue_t queue_ref(void) {
if (!queue) {
queue = dispatch_queue_create_with_target("GlobalDispatchQueue", DISPATCH_QUEUE_SERIAL, dispatch_get_main_queue());
}
return queue;
}
To use:
#include "GlobalQueue.h" in any Objective-C or C implementation source file.
Call queue_ref() to use the dispatch queue. Once queue_ref() has been called, the queue can be used via the queue variable in all source files
Examples:
Calling queue_ref():
dispatch_queue_t serial_queue_with_queue_target = dispatch_queue_create_with_target("serial_queue_with_queue_target", DISPATCH_QUEUE_SERIAL, **queue_ref()**);
Calling queue:
dispatch_queue_t serial_queue_with_queue_target = dispatch_queue_create_with_target("serial_queue_with_queue_target", DISPATCH_QUEUE_SERIAL, **queue**));]
Just do
void * getSingleTon() {
static Class object = (Class *)malloc( sizeof( Class ) );
return &object;
}
which works in a concurrent environment too.