Question on c and objective-c communication

Discussion in 'Mac Programming' started by youngplayer, Jul 23, 2008.

  1. youngplayer macrumors member

    Joined:
    May 16, 2008
    Location:
    Shanghai,China
    #1
    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.
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    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
     
  3. youngplayer thread starter macrumors member

    Joined:
    May 16, 2008
    Location:
    Shanghai,China
    #3
    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?
     
  4. kpua macrumors 6502

    Joined:
    Jul 25, 2006
    #4
    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.
     
  5. youngplayer thread starter macrumors member

    Joined:
    May 16, 2008
    Location:
    Shanghai,China
    #5
    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.
     
  6. youngplayer thread starter macrumors member

    Joined:
    May 16, 2008
    Location:
    Shanghai,China
    #6
    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!
     
  7. kpua macrumors 6502

    Joined:
    Jul 25, 2006
    #7
    -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.
     
  8. youngplayer thread starter macrumors member

    Joined:
    May 16, 2008
    Location:
    Shanghai,China
    #8
    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?
     
  9. kpua macrumors 6502

    Joined:
    Jul 25, 2006
    #9
    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"));
    }
    
     
  10. youngplayer thread starter macrumors member

    Joined:
    May 16, 2008
    Location:
    Shanghai,China
    #10
    Thank you for your advice. I'll try later.
     
  11. youngplayer thread starter macrumors member

    Joined:
    May 16, 2008
    Location:
    Shanghai,China
    #11

    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?
     
  12. youngplayer thread starter macrumors member

    Joined:
    May 16, 2008
    Location:
    Shanghai,China
    #12
    I've tried the objc_msgSend method. It does work. Thank you!
    Additionaly, how to pass parameters by this method?
     

Share This Page