use of undeclared identifier

Discussion in 'Mac Programming' started by spt, Aug 1, 2011.

  1. spt
    macrumors member

    Joined:
    Oct 27, 2009
    #1
    I would like to build a simple interface around some c-code I have. I've spend over two hours now on a seemingly simple problem with Objective C.

    It simply seems impossible to call an Objective C function from within a normal c function. If I do, for example:

    void changeInfo()
    {
    [TextField setIntValue:test];
    }

    I get an error that says "Use of undeclared identifier 'TextField'". Whereas if this piece of code would be like this:

    - (void) changeInfo
    {
    [TextField setIntValue:test];
    }

    ... it would work perfectly fine.

    What am I doing wrong...?
     
  2. macrumors 6502

    Joined:
    Jul 25, 2006
    #2
    Your 'TextField' variable isn't global—it's an instance variable of your class.

    Objective-C methods have two implicit parameters that you don't see directly in the code: 'self' (a pointer to the object the method is called on) and '_cmd' (the selector of the method being called). When you access 'TextField', the code that gets generated is actually 'self->TextField'.

    In a plain C function, there can be no implicit parameters, so even if your C function is defined inside your @implementation, it won't be able to find 'TextField', because it doesn't even know what 'self' is.

    One thing I often do is just make an explicit 'self' parameter in plain C functions, and then access the ivars explicitly with 'self->TextField'. The compiler won't complain about @private or @protected ivars as long as the function definition is within the @implementation of your class.
     
  3. macrumors 6502a

    GorillaPaws

    Joined:
    Oct 26, 2003
    Location:
    Richmond, VA
    #3
    Is TextField an iVar? If so, it should be textField because the leading character should only be caps if it's a Class name, not an instance of a class.

    The issue you're having is one of the scope of your variables. In your function example, since you haven't passed in a reference to your textField object, your code won't be able to access it. For example, this should work:
    Code:
    void changeInfo( NSTextField *aTextField )
    {
         [aTextField setIntValue:test];
    }
    Whereas the method version will work if "aTextField" is declared as an ivar of the Class you're working in. All instance methods have access to the ivars of the instances of their class.
     
  4. spt
    thread starter macrumors member

    Joined:
    Oct 27, 2009
    #4
    Thanks a lot for your comments, it now works!

    Code:
    void changeInfo( NSTextField *aTextField )
    {
         [aTextField setIntValue:test];
    }
    Using a global did the trick.

    The above suggestion would be quite complex in this specific case, as the c-program involves starting a lot of threads using the pthread library. The thread functions thus can't easily be started with an argument.
     
  5. macrumors 603

    Joined:
    Aug 9, 2009
    #5
    The function prototype for pthread_create():
    Code:
         int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void
                            *(*start_routine)([COLOR="Blue"]void *[/COLOR]), [COLOR="Red"]void *arg[/COLOR])
    
    The blue-hilited part declares that start_routine is a function with a single parameter, whose type is pointer-to-void. The red-hilited parameter is the actual argument value to pass to the function.

    From the man-page for pthread_create():
    The thread is created executing start_routine with arg as its sole argument. ​
     
  6. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #6
    Reading up on "blocks" and "Grand Central Dispatch" will safe you an awful, awful lot of headaches. Us as well. :D
     

Share This Page