Re: How to define a method IMP for use as a C callback?
Re: How to define a method IMP for use as a C callback?
- Subject: Re: How to define a method IMP for use as a C callback?
- From: "b.bum" <email@hidden>
- Date: Tue, 23 Mar 2004 08:41:04 -0800
On Mar 23, 2004, at 12:59 AM, Ken Tozier wrote:
I'm working with the ICA architecture and need to define an IMP for one
of my methods so it can be called as a C function by the ICA runtime. I
got it to the point where it does enter the method, when a camera is
plugged in, but the passed in parameter is always NULL. I'm sure I'm
just making a syntax error but can't figure it out. Could someone point
out what I'm doing wrong?
The ICARegisterEventNotificationPB structure is defined as follows...
struct ICARegisterEventNotificationPB {
ICAHeader header;
ICAObject object; /* <-> */
OSType notifyType; /* <-> */
ICACompletion notifyProc; /* <-- */
};
typedef struct ICARegisterEventNotificationPB
ICARegisterEventNotificationPB;
... the notifyProc field -- the one you are trying to fill with your
callback -- is declared like this...
typedef struct ICAHeader ICAHeader;
typedef CALLBACK_API_C( void , ICACompletion )(ICAHeader * pb);
As you had indicating in your code...
typedef void (*HandleMessageIMP)(id, SEL,
ICARegisterEventNotificationPB *);
HandleMessageIMP doHandleMessage = (HandleMessageIMP)[self
methodForSelector:@selector(handleNotification:)];
... an objective-c method IMP that you want to use to handle
notifications is really just a C function that takes three arguments;
self, the SEL name of the method, and a pointer to an ICA struct.
However, the callback mechanism has no idea what self and SEL to use
when calling your function. But lets not even consider Objective-C
for a moment. The ICA callback function takes only one argument.
So, you need to register a callback function that takes a single
argument -- a standard C function written in the traditional pure
Carbon stylings required by the ICA API. If you want to call into
ObjC from that callback function, you will need to stash an object
reference somewhere and call the method as you normally would from
within your callback function.
void myCallBackFunc(ICARegisterEventNotificationPB *foo) {
id notifObjectToCall = .... foo.bar or whatever to get the instance of
your object to call ...
[notifObjectToCall handleNotification: foo];
}
Finding a spot to stash the object pointer is always a challenge. As
long as you can stash a (void *)s worth of arbitrary data in the
structure passed back to the callback, then it is easy....
If you can't, then you'll need to use a global variable, or provide a
hook in your app somewhere to grab the correct object to reference.
Neither of which will work in a threaded application where multiple
threads may be making simultaneous, but different, callbacks. In that
case, you'll need to add the callback object to the current thread's
dictionary or stash it somewhere else (inner function, anyone?).
b.bum
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.