Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

youngplayer

macrumors member
Original poster
May 16, 2008
36
0
Shanghai,China
As we known, the objective-c calls the c functions very smoothly. But how can C call objective-c functions?

For example, there's a callback function in a c file triggered, I want to to let the UI (which is written in objective-c ) know to change appearence.

I've not got document on such topic. If you know, please tell me. Thanks.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
you'll need a pointer to the object you want to send a message to. Once you have that you can just pass a message as you would anywhere. If you are needing to pass a message to a class you don't need anything, just pass the message.

-Lee
 

youngplayer

macrumors member
Original poster
May 16, 2008
36
0
Shanghai,China
you'll need a pointer to the object you want to send a message to. Once you have that you can just pass a message as you would anywhere. If you are needing to pass a message to a class you don't need anything, just pass the message.

-Lee

Sure. I've tried to declare an objective-c object in c file, but failed for compiling errors.

Could you show me some example, or some document related?
 

kpua

macrumors 6502
Jul 25, 2006
294
0
Usually, there's little reason why you cannot just rename the file to .m to let the compiler recognize Objective-C syntax. However, for those cases where you can't, you can send any message to an object, given you have its pointer, with objc_msgSend(<pointer>, <selector> [, arguments]). You can also use any of the functions in the objc_*.h headers.

Of course, for any of this, you have to link in libobjc.
 

youngplayer

macrumors member
Original poster
May 16, 2008
36
0
Shanghai,China
Usually, there's little reason why you cannot just rename the file to .m to let the compiler recognize Objective-C syntax. However, for those cases where you can't, you can send any message to an object, given you have its pointer, with objc_msgSend(<pointer>, <selector> [, arguments]). You can also use any of the functions in the objc_*.h headers.

Of course, for any of this, you have to link in libobjc.

I'm not whether your advice is to solve my problem.
Let me show an simple example:
//SimpleC.h: ignored
// a simple c file: SimpleC.c
//SimpleC.c contents start


void cFunction(void){
// How to call functions in SimpleObj.m here???

}
//SimpleC.c contents end

// SimpleObj.h:ignored
//a simple objective-c file: SimpleObj.m

//SimpleObj.m contents start
#include SimpleC.h
@implment SimpleObj
-(void) objective-cFuntion{
//call c function
cFunction(); // it's ok to call function in SimpleC.c when include SimpleC.h
}

//SimpleObj.m contents end

Notice:"How to call functions in SimpleObj.m here???" This is my question.
 

youngplayer

macrumors member
Original poster
May 16, 2008
36
0
Shanghai,China
I've got a solution which using CFNotification.
And I find another strange thing....

continue the sample:

// in the SimpleC.c
//I added these codes:

void cFunction{
CFMutableDictionaryRef info = CFDictionaryCreateMutable(NLL,1,NULL);
CFDictionaryAddValue(info,CFSTR("key"),CFSTR("value"));
CFNotificationCenterRef center = CFNotificationCenterGetLocalCenter();
CFNotificationCenterPostNotification(center,CFSTR("MyNotification"),NULL, info, true);

}

//in SimpleObj.m
//I added these code:

-(id)init{
if(self = [super init]){
[[NSNotificationCenter defaultCenter] addObserver:self selector:mad:selector(somethingTodo: ) name:mad:"MyNotification" object:nil];
}
}

-(void) somethingTodo: (NSNotification *) n{
NSDictionary * info = [[n userInfo] retain];
CFShow(info); // the info is shown here
NSLog(@"info's value==%@",[info valueForKey:mad:"key"]); // it's null
}

The strange thing is that in somethingTodo function CFShow returns the info with values, but the valueForKey returns null.

Who knows in detail? pls share the experience with us, thank you!
 

kpua

macrumors 6502
Jul 25, 2006
294
0
-valueForKey: is a KVC method. -objectForKey: is the correct method for accessing the dictionary.

Also, CFShow(dict) is roughly equivalent to NSLog(@"%@", dict) -- this will cause the entire contents of the dictionary to be printed out, like CFShow() does.
 

youngplayer

macrumors member
Original poster
May 16, 2008
36
0
Shanghai,China
-valueForKey: is a KVC method. -objectForKey: is the correct method for accessing the dictionary.

Also, CFShow(dict) is roughly equivalent to NSLog(@"%@", dict) -- this will cause the entire contents of the dictionary to be printed out, like CFShow() does.

The problem seems caused by CFSTR("key") and @"key", are they different?

When I change the CFSTR("key") to a "CFStringRef KEY = CFStringCreateWithCString(NULL,"key",KCFStringEncodingUTF8);" , it doen't work either. The value of objectForKey:mad:"key" still is null.

And I notice that the type of key in CFDictionary is "void *", and the type of key in NSDictionary is "NSString *". Will these difference cause some unexpected result?

After all, how can I get the value of the NSDictionary which is trasferred from a object of CFDictionary?
 

kpua

macrumors 6502
Jul 25, 2006
294
0
CFSTR("key") and @"key" should return YES from isEqual: because they are equivalent through toll-free bridging. This should be enough for the dictionary to work.

Your code works for me:

Code:
% ./a.out
<CFDictionary 0x109a40 [0xa0049020]>{type = mutable, count = 1, capacity = 3, pairs = (
	1 : <0x2040> = <0x2060>
)}
2008-07-24 20:40:41.263 a.out[10152:807] info's value==value

I still don't know why you don't just do this from your C file:

Code:
#include <objc/runtime.h>

static void *myObjCObj = NULL;
void registerObjectiveCObject(void *obj) {
    myObjCObj = obj;
}

void callAnObjectiveCMethod() {
    objc_msgSend(myObjCObj, sel_getUid("anObjCMethod"));
}
 

youngplayer

macrumors member
Original poster
May 16, 2008
36
0
Shanghai,China
CFSTR("key") and @"key" should return YES from isEqual: because they are equivalent through toll-free bridging. This should be enough for the dictionary to work.

Your code works for me:

Code:
% ./a.out
<CFDictionary 0x109a40 [0xa0049020]>{type = mutable, count = 1, capacity = 3, pairs = (
	1 : <0x2040> = <0x2060>
)}
2008-07-24 20:40:41.263 a.out[10152:807] info's value==value

I still don't know why you don't just do this from your C file:

Code:
#include <objc/runtime.h>

static void *myObjCObj = NULL;
void registerObjectiveCObject(void *obj) {
    myObjCObj = obj;
}

void callAnObjectiveCMethod() {
    objc_msgSend(myObjCObj, sel_getUid("anObjCMethod"));
}

Thank you for your advice. I'll try later.
 

youngplayer

macrumors member
Original poster
May 16, 2008
36
0
Shanghai,China
CFSTR("key") and @"key" should return YES from isEqual: because they are equivalent through toll-free bridging. This should be enough for the dictionary to work.

Your code works for me:

Code:
% ./a.out
<CFDictionary 0x109a40 [0xa0049020]>{type = mutable, count = 1, capacity = 3, pairs = (
	1 : <0x2040> = <0x2060>
)}
2008-07-24 20:40:41.263 a.out[10152:807] info's value==value

I still don't know why you don't just do this from your C file:

Code:
#include <objc/runtime.h>

static void *myObjCObj = NULL;
void registerObjectiveCObject(void *obj) {
    myObjCObj = obj;
}

void callAnObjectiveCMethod() {
    objc_msgSend(myObjCObj, sel_getUid("anObjCMethod"));
}


I'm sorry for asking the same question again and again. But The code doesn't work on my Mac.

I've tried again today, and the result is as follwing:
<CFDictionary 0x109a40 [0xa0049020]>{type = mutable, count = 1, capacity = 3, pairs = (
1 : <0x2040> = <0x2060>
)}
2008-07-24 20:40:41.263 a.out[10152:807] info's value==(null)

Did you modify some codes? As I check, one of sentence(CFMutableDictionaryRef info = CFDictionaryCreateMutable(NLL,1,NULL); ) I present is wrong for my mistake. Anything else do you do before you get the correct result?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.