View Full Version : Question on c and objective-c communication
youngplayer
Jul 23, 2008, 04:47 AM
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
Jul 23, 2008, 09:05 AM
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
Jul 23, 2008, 09:10 PM
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
Jul 23, 2008, 10:06 PM
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
Jul 24, 2008, 12:44 AM
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
Jul 24, 2008, 03:05 AM
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:@selector(somethingTodo: ) name:@"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:@"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
Jul 24, 2008, 10:36 AM
-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
Jul 24, 2008, 09:54 PM
-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:@"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
Jul 24, 2008, 11:47 PM
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:
% ./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:
#include <objc/runtime.h>
static void *myObjCObj = NULL;
void registerObjectiveCObject(void *obj) {
myObjCObj = obj;
}
void callAnObjectiveCMethod() {
objc_msgSend(myObjCObj, sel_getUid("anObjCMethod"));
}
youngplayer
Jul 27, 2008, 09:51 PM
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:
% ./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:
#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
Aug 7, 2008, 02:23 AM
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:
% ./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:
#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?
youngplayer
Aug 7, 2008, 02:51 AM
I've tried the objc_msgSend method. It does work. Thank you!
Additionaly, how to pass parameters by this method?
vBulletin® v3.8.6, Copyright ©2000-2012, Jelsoft Enterprises Ltd.