3

I have a function that executed in c. When a certain condition is met I want to change the state of a UIButton. I was trying to dispatch an NSNotification but that doesnt work.

What would be a good way to send a message to an obj-c object from a c function?

Ideally I would like to somehow be able to use NSNotification

4 Answers 4

5

The C Code needs to be inside of a .m file. If it is not then add a C callback function inside your .m that can post your notification or do something else for you. Here is an example of accessing the Objective-C class that calls a C function outside of a .m file.

//SomeCCode.c
void someCFunction(int somevar, void (callback) (void*) , void *context)
{
    doSomething(somevar);
    callback(context);
}

//SomeClass.m
void someCCallbackInObjC(void *context)
{
    SomeClass *myclass = (SomeClass*)context;
    //Access my class or just post notification
}

@implementation SomeClass

...
-(void)someMethod
{
    someCFunction(0, someCCallbackInObjC, self);
}
...

@end
Sign up to request clarification or add additional context in comments.

Comments

2

Simply compile your C files as Objectice-C; and access NSNotificationCenter as usual.

Unlike C++, Objective-C imparts no compatibility pitfalls on C code. All and any C code is also valid Objective-C code, assuming the underlying standard used is the same.

Edit: To elaborate: as long as you use the Objective-C compiler; there's no difference between what you can do in a method and a function; except that self and super aren't available for use in C functions unless you define them yourself.

Reedit: In order to define self in a C function; simply define it as follows:

notifyingFunction(id self, /* other arguments */);

and pass any appropriate self when calling the function.

3 Comments

thats eactly the problem I have, I dont know how to define self for use within the c function
Remember C functions are static and do not have any knowledge of a class instances. That is why you need to pass information to the C function such as a context.
What if the c function is a call-back function from a c library? In that case, how can we access self inside that call-back c function which is written inside .m file.
1

I've spent quite a while to find the solution to post notifications from C to Objective C for my OS X app developed with XCode 5 on Mavericks. Joe's answer was the only working solution for me with XCode 5 on Mavericks. I had to add bridging though. So, my app has code similar to the following:

//SomeCCode.c - no changes here
void someCFunction(int somevar, void (callback) (void*) , void *context)
{
    doSomething(somevar);
    callback(context);
}

//SomeClass.m
void someCCallbackInObjC(void *context)
{
    // change #1: added __bridge in type cast
    SomeClass *myclass = (__bridge SomeClass*)context;
    //Access my class or just post notification
}

@implementation SomeClass

...
-(void)someMethod
{
    // change #2: added the type cast with __bridge for self
    someCFunction(0, someCCallbackInObjC, (__bridge void*) (self));
}
...

@end

Comments

0

I was messing around a lot with this so
just in addition:
I am using a c unit, which i don't want to rename to *.m files. And I need a log called from there.
No wrappers could help me to avoid linker errors.
So I used the following pattern:
I made hpp and cpp files Added an extern variable - pointer to a function to header:

extern void (*transLogFun) (const char *,...);

and its definition to cpp file

void (*transLogFun) (const char *,...) = NULL;

Then i created an h and mm file: h:

#import <UIKit/UIKit.h>
#import "fff.hpp"

void ioslogfun(const char *s, ...);

In mm file i wrote a function and a class with its object like this:

#import "zzz.h"
#import <Foundation/Foundation.h>

void ioslogfun(const char *s, ...){
    va_list vl;
    va_start(vl,s);
    char *str;
    vasprintf(&str,s,vl);
    va_end(vl);
    NSLog([NSString stringWithUTF8String:str]);
    free(str);
}

class Fff{
public:
    Fff(){
        transLogFun = &ioslogfun;
    }
};

Fff initiator;

And where-ever i called the transLogFun(...) it worked fine.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.