iPick12
iPick12

Reputation: 21

Getting the address of an Objective-C method

I am new to Objective-C and I need to overcome the following issue. I am trying to develop a front-end for a C library and I need to somehow get the address of an Objective-C member function and pass it to the library.

For instance: here's what I would do in C++

class MyClass
{
    public:
    void my function();
    void some_other_function()
    { connect_signal(my_function); }
};

Here, I just pass the address of my_function() to connect_signal. Is that possible in Objective-C? Any other ideas?

My second choice would be to simply write a C function out of the class that would call the Objective-C function.

Thanks in advance

Upvotes: 1

Views: 2252

Answers (3)

Seva Alekseyev
Seva Alekseyev

Reputation: 61396

For the record, you can't connect a signal to a nonstatic C++ function. At least not in the *nix meaning of signals. Those need a this pointer for invokation.

Now, about Objective C. Depends on what do you want to do - pass a pointer to an Objective C method to a plain-C API, or implement a signal-like callback mechanism of your own. Other answers concentrate on the former; let's talk the latter.

The natural thing to do is passing around a combination of a selector and an object pointer. Selectors have datatype SEL and are retrieved using the @selector() construct. A selector is a piece of data (really an integer) that uniquely identifies a method within a class hierarchy.

Let's imagine you have a connect_signal function somewhere that wants a callback:

-(void)connect_signal:(SEL)callbackSelector forObject:(NSObject*)callbackObject;

You call it like this (from within the callback object):

[xx connect_signal:@selector(MyMethod:) forObject:self];

Within the function, you save the selector and the object pointer. When you need to invoke the callback, you would issue the following call:

[SavedCallbackObject performSelector:(SavedCallbackSelector) withObject: nil];

The second parameter is for passing parameters to the callback; if you need more than one, see NSInvoke.

My answer is assuming Cocoa. NSObject, e. g. is a Cocoa class. It's a safe bet for ObjC questions these days, considering.

Or you can use good old function pointers. They're still around.

Upvotes: 3

bbum
bbum

Reputation: 162722

An Objective-C method implementation (IMP) is a C function that takes at least two arguments; the target of the method call (self) and the selector to be invoked (_cmd).

Thus, passing an IMP to your C API won't work.

Your best bet is to pass a C function. Assuming your C API is sensible and has an "arbitrary user context pointer thingy", something like:

void myfunc(void *context) {
    [(MyClass *)context callback];
} 

Upvotes: 2

zoul
zoul

Reputation: 104125

There’s a methodForSelector: method that returns an IMP, a pointer to the implementation of a method for given selector (related question). Is that what you’re after?

And as a more general remark, using a pointer to a method implementation is usually too much magic. Is there a higher-level, more “ordinary” solution to your use case? (I can’t really imagine the details from what you wrote in the question.)

Upvotes: 5

Related Questions