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

TurboLag

macrumors member
Original poster
Feb 24, 2004
85
0
I am trying to access some instance variables from a C function in the same source file. Declaring the instance variables as public does not make them visible, so the only alternative is to declare them outside the @interface, thus making them global. I am sure this is not the proper approach.

Also, how can I call a method from within the C function if the object itself is not visible?

Thanks.
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
C functions work the same in Objective-C as they do in C++. They can't access instance variables or methods. You need to pass in a reference of your class to the function and then you can do whatever you want. For example:

Code:
void myNiftyFunc(SomeObject *obj) {
    id ivar = [obj ivar];
}


@implementation SomeObject

- (void)blah {
    myNiftyFunc(self);
}

- (id)ivar {
   return someIvar;
}

@end
 

TurboLag

macrumors member
Original poster
Feb 24, 2004
85
0
The problem is that the C function is a callback routine, and I cant change how it is called. So I am stuck with the parameters it is defined with:

Code:
void callback  (void * target, unsigned long result, void * refcon, void * sender);

The setup for the callback is:

Code:
HIDresult = HIDSetQueueCallback (pFoundDevice, (IOHIDCallbackFunction)callback);

I could try wrapping the function as a ObjC method, such as:
Code:
- (void)callback:  (void *) target Result:(unsigned long) result  Refcon:(void *) refcon Sender:(void *) sender;

but I can't figure the proper syntax for the HIDSetQueueCallback function call. Any advice?
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Usually with a callback function you can setup it up to pass in a pointer, and for Objective-C you would pass in self, but for what you're doing I don't think it's possible since HIDSetQueueCallback() only takes two arguments.

Edit: looks like you're using some code from Apple's examples. They end up just calling setEventCallout() which sets up your callback. Looks like it could be changed to work around the issue but it'd probably be easier to use a global variable (ugly though).
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
I feel somewhat dirty suggesting this, but it may work:

Have a global pointer defined in a file that points to the type of the object that has the member you need access to. In this file, define 2 functions:

Code:
objecttype *globalobj;

registerObject(objecttype *myobj) {
  globalobj = myobj;
}

id getIvar() {
  return [globalobj ivar];
}

Before any of the "worker" code, call registerObject passing the instance of your object where you have it available, or registerObject(self) from a method in your object instance.

Then in your callback function, you can call getIvar. This isn't really any better than having a global variable with the value in it, but it at least keeps you from having to keep that value "synchronized" with the objects member.

-Lee
 

Krevnik

macrumors 601
Sep 8, 2003
4,100
1,309
Since everyone else is throwing in information, I'll throw in my two cents: refcons are your friend in this case.

When you setup the callback, you want to also search around for how to set the refcon on the callback. The poster a couple posts above me has the same idea. You set the refcon to the Obj-C object you need to call into from the callback, and then from the C method, you can typecast refcon into the Obj-C object and call into it.

EDIT: I randomly stumbled on this post on the Apple dev lists which includes an updated HIDSetQueueCallback which will let you pass in a refcon pointer. Use it wisely. :)

http://lists.apple.com/archives/mac-games-dev/2002/Nov/msg00018.html
 

TurboLag

macrumors member
Original poster
Feb 24, 2004
85
0
Thanks Krevnik.

Works like a charm. I pass the setup function a pointer to my object, then typecast it in the callback. Much cleaner approach.

Now to remove those global variables . . .
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.