Resolved C-call and Obj-C function

Discussion in 'Mac Programming' started by DennisBlah, Feb 15, 2018.

  1. DennisBlah, Feb 15, 2018
    Last edited: Feb 15, 2018

    DennisBlah macrumors 6502

    DennisBlah

    Joined:
    Dec 5, 2013
    Location:
    The Netherlands
    #1
    Hi all,

    I'm trying to hit: [myTableView reloadData] from a C function.

    Is there anyone who can help me here?

    ————
    I just made a static variable of the tableview within the class and defined it in viewdidload
    it works now just like the obj-c wrapper call
     
  2. Senor Cuete macrumors 6502

    Joined:
    Nov 9, 2011
    #2
    Objective C is a superset of C. A compiler that can compile Objective C also compiles C. I wonder if you could put your code in a .m file and run it. The compiler would understand the [myTableView reloadData] statement.You would need to #import <Cocoa/Cocoa.h>.
     
  3. DennisBlah thread starter macrumors 6502

    DennisBlah

    Joined:
    Dec 5, 2013
    Location:
    The Netherlands
    #3
    Hi Senor Cuete,

    Thanks for your response!
    I did try it just now, as I found a little time.
    Basically my code is a usb monitor, and is called from didFinishLoading.

    The trigger DeviceAdded (which is a C function) can't do [myTableView reloadData];
    Even when I imported Cocoa.h to the project. It shows "Use of undeclared identifier 'myTableView'"
    The tableView is declared in .h file and synthesized in .m

    Nevertheless in case I need more functions and as lazy as I am (I also have some obj-c functions I need to call from C now...) I now implemented as following
    "static AppDelegate *myDelegate"
    And I call [[myDelegate myTableView] reloadData]; and works fine :)
    Code:
    //Start usb monitor below
        CFMutableDictionaryRef  matchingDict;
        CFRunLoopSourceRef      runLoopSource;
        kern_return_t           kr;
    
        matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
        if (matchingDict == NULL) {
            fprintf(stderr, "IOServiceMatching returned NULL.\n");
        }
        gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault);
        runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort);
        gRunLoop = CFRunLoopGetCurrent();
        CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode);
        kr = IOServiceAddMatchingNotification(gNotifyPort,
                                              kIOFirstMatchNotification,
                                              matchingDict,
                                              DeviceAdded,
                                              NULL,
                                              &gAddedIter
                                              );
    
     
  4. Krevnik macrumors 68040

    Krevnik

    Joined:
    Sep 8, 2003
    #4
    As a sort of "for the future" response, you can also do something slightly different if you want to keep some code using the C/C++ compiler instead of using the Obj-C compiler:

    Code:
    //----- MyObjCType.h
    #ifdef __OBJC__
    @interface MyObjCType : NSObject
    {
        - (void)reloadData;
    }
    
    typedef MyObjCType *MyObjCTypeRef;
    #else
    typedef void *MyObjCTypeRef;
    #endif
    
    void ReloadDataForMyObjCType(MyObjCTypeRef targetObject);
    
    //----- MyObjCType.m
    // <Insert ObjC Code Somewhere Here>
    void ReloadDataForMyObjCType(MyObjCTypeRef targetObject)
    {
        [targetObject reloadData];
    }
    
    //----- MyCCode.c
    
    void MyFunctionDoesAThing()
    {
        MyObjCTypeRef targetObject = GetSomeTypeRef();
        ReloadDataForMyObjCType(targetObject);
    }
    
    This pattern will hide the Obj-C code away from the C code and still make it callable from C code by using the typedef trickery.
     
  5. DennisBlah thread starter macrumors 6502

    DennisBlah

    Joined:
    Dec 5, 2013
    Location:
    The Netherlands
    #5
    I did not try it, but will definitely do so in future!
    Thats awesome thank you very much
     

Share This Page

4 February 15, 2018