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

TheLee

macrumors member
Original poster
Aug 5, 2006
71
0
Hi, so how do you pass function pointers via class/instance methods in obj-c?

It should be possible, right? I mean, IMP is a typedef for a function pointer, so something like
Code:
- (void) foo:(IMP)bar;
is valid.

So how do you do other types of function pointers? I mean... I guess I could typedef all the function pointer types I want, but that just sounds really ugly.
 

savar

macrumors 68000
Jun 6, 2003
1,950
0
District of Columbia
Hi, so how do you pass function pointers via class/instance methods in obj-c?

It should be possible, right? I mean, IMP is a typedef for a function pointer, so something like
Code:
- (void) foo:(IMP)bar;
is valid.

So how do you do other types of function pointers? I mean... I guess I could typedef all the function pointer types I want, but that just sounds really ugly.

In Objective-C, those thing-a-ma-jigs are called "selectors", not functions.

They are dispatched quite differently from C functions, due to the fact that they need to support the dynamic nature of Objective-C. But you can pass these structures as parameters just the same by using the @selector() directive.

http://www.faqs.org/faqs/computer-lang/Objective-C/faq/
 

TheLee

macrumors member
Original poster
Aug 5, 2006
71
0
I'm well aware of them being selectors.

The thing is, while other places in my program, I've gladly accepted SEL objects, the method I'm trying to implement merely wants a brief callback function pointer (essentially just returning an integer to ostenibly use to update a status bar). I'm just tryign to have to add a class method or instance method in every object that wants to support the callback, as I would have to make these publically declared whereas I could ostensibly use a statically-linked function.

IMP, while it can be treated as a selector, is defined as
Code:
typedef id (*IMP)(id, SEL, ...)
with its implicit arguments, so I know at the very least you can pass function pointers to methods by using typedefs... but I also want to avoid the ugliness of having to declare a typedef everytime I want to create a function pointer.
 

TheLee

macrumors member
Original poster
Aug 5, 2006
71
0
well, after a bit of experimentation, i figured it out.

In case anyone else wants to know, if you ever feel like passing a function pointer to an objective-c method, a quick example is
Code:
@interface Something: Object {
}
 - (void) foo:(int(*)(void))bar;
@end

@implementation Something
- (void) foo:(int(*)(void))bar {
   return (*bar)();
}
@end

int someFunc( void ) {
    return 9;
}

int main ( int argc, char **argv ) {
    Something *object = [[Something alloc] init];

    printf( "%i\n", [object foo:&someFunc] );

    [object release];

    return 0; 
}

The key being that the signature for passing a function pointer is
Code:
(return_type (*) (argument_list))

you'd think that this would be documented somewhere...
 

shawnl

macrumors newbie
Sep 16, 2008
4
0
Great info TheLee,

Could you help me out with some similar functionality? What I need to do is pass my class a function like you do but instead of passing it into a method where it is automatically called I need to pass it into a property for the class to store until it needs to invoke the method but I am having trouble getting he syntax down.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
Great info TheLee,

Could you help me out with some similar functionality? What I need to do is pass my class a function like you do but instead of passing it into a method where it is automatically called I need to pass it into a property for the class to store until it needs to invoke the method but I am having trouble getting he syntax down.

Here is C code to store a function pointer:
Code:
#include <stdio.h>

void myMethod(int,double);

int main(int argc, char *argv[]) {
  void (*callback)(int,double) = NULL;
  callback = &myMethod;
  callback(1,5.);
}

void myMethod(int argOne,double argTwo) {
  printf("One is: %d, two is: %e\n",argOne,argTwo);
}

If you really wanted to do this, the field in your class would be:
returntype (*nameOfField)(type1,type2,...);

I don't know why you would do this unless there were C methods that you had to call that were in a library, and you couldn't reproduce their functionality in a class. Otherwise, you could just store a SEL instead.
http://developer.apple.com/document.../ObjectiveC/Articles/chapter_9_section_3.html

If there are numerous functions that might be called, you could wrap each one in a method of a particular class, and store the SEL to the proper method instead of the raw C function pointer.

-Lee
 

darkwing

macrumors 65816
Jan 6, 2004
1,210
0
You don't need to put the & before somefunc. In C, it's implicit if you don't put parenthesis after somefunc to actually call it. I'm assuming the same behavior is true for obj-c which is a strict superset of C.
 

shawnl

macrumors newbie
Sep 16, 2008
4
0
Here is my situation.. I have one class lets call Class1 and it creates an instance of a second Class (Class2). What I need to do is make a method in Class2 that when invoked actually references a method in Class1. I was going to simply add a reference back to Class1 from Class2 but that means they would have to reference each other's .h files which appears to throw an error.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
Here is my situation.. I have one class lets call Class1 and it creates an instance of a second Class (Class2). What I need to do is make a method in Class2 that when invoked actually references a method in Class1. I was going to simply add a reference back to Class1 from Class2 but that means they would have to reference each other's .h files which appears to throw an error.

You're not going to get a function pointer to an objective-C class or instance method. It may be possible, but it's a bad idea. This thread discusses a workaround to classes having one another as fields, and avoiding the include problem:
https://forums.macrumors.com/threads/561949/

If it's a single method you need to call in the class, you have no need to store the function itself at all, you'd just invoke it. if you need to call different classes based on some condition, it still seems like you could do this with a switch statement, but if you absolutely needed to dynamically deal with functions you should look into using SEL as I linked above.

-Lee
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,566
Hi, so how do you pass function pointers via class/instance methods in obj-c?

It should be possible, right? I mean, IMP is a typedef for a function pointer, so something like
Code:
- (void) foo:(IMP)bar;
is valid.

So how do you do other types of function pointers? I mean... I guess I could typedef all the function pointer types I want, but that just sounds really ugly.

An IMP is not a function pointer. Let me explain:

A SEL is a selector - it can be used to invoke a message, with all the mechanisms that Objective-C uses for Objective-C message lookup.

An IMP is a selector that has been resolved for one specific Objective-C class. An IMP can therefore be used to invoke that specific message, but only if the object in question belongs to the right class; if it is used with the wrong kind of object, your program will most likely crash.

A function pointer - well, just check in any of the thousands of books about the C language what a function pointer is.

If you want to be able to pass any function pointer as an argument, just cast it to
Code:
void (*) (void)
. But when you want to call the function, the caller has to know the correct function type and cast the function pointer accordingly. It is obviously safer to not do this casting but to use just the right function pointers so that the compiler can detect problems.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.