Function Pointers in Objective C
Typically, you need two pieces of information to call back into Objective-C; the method to be invoked and the object to invoke it upon. Neither just a selector or just the IMP -- the instanceMethodForSelector:
result -- will be enough information.
Most callback APIs provide a context pointer that is treated as an opaque value that is passed through to the callback. This is the key to your conundrum.
I.e. if you have a callback function that is declared as:
typedef void (*CallBackFuncType)(int something, char *else, void *context);
And some API that consumes a pointer of said callback function type:
void APIThatWillCallBack(int f1, int f2, CallBackFuncType callback, void *context);
Then you would implement your callback something like this:
void MyCallbackDude(int a, char *b, void *context) {
[((MyCallbackObjectClass*)context) myMethodThatTakesSomething: a else: b];
}
And then you would call the API something akin to this:
MyCallbackObjectClass *callbackContext = [MyCallbackObjectClass new];
APIThatWillCallBack(17, 42, MyCallbackDude, (void*)callbackContext);
If you need to switch between different selectors, I would recommend creating a little glue class that sits between the callback and the Objective-C API. The instance of the glue class could contain the configuration necessary or logic necessary to switch between selectors based on the incoming callback data.
Function pointers in Objective C
Here pNewMsgeFunc is the alias name of the function pointer tNewMsg which is created inside the structure stRsStruct
No, it's not. tNewMsg
is a name that identifies a type.
typedef RsMsg* (*tNewMsg)(void);
...but pNewMessageFunc
is an object of that type.
Look at it this way. In this code:
typedef unsigned int uint;
uint n = 42;
n
is not an alias of uint
. Rather, n
is a variable of type uint
.
So, pNewMessageFunc
is a global variable (of type pointer-to-function-which-takes-no-parameters-and-returns-pointer-to-RsMsg
) which you never initialize.
Modifying a function pointer passed to a method?
This can be done using pointers to function pointers. Perhaps the most readable way to do it is to typedef
your function pointer, like this:
typedef void (*FunPtr)(int a, float b);
Then use a pointer of that typedef
-ed type to assign in a function, like this:
void foo(int a, float b) {
printf("FOO : %d %f\n", a, b);
}
void bar(int a, float b) {
printf("BAR : %d %f\n", a, b);
}
// This function receives a pointer to function pointer
void assign(int n, FunPtr *ptr) {
if (n == 0) {
*ptr = foo;
} else {
*ptr = bar;
}
}
Here is how you call assign
from your code:
int main(void) {
FunPtr f;
assign(0, &f);
f(10, 20.5);
assign(1, &f);
f(10, 20.5);
return 0;
}
Demo.
Note: You are right about blocks in Objective-C greatly reducing the need for direct use of function pointers. However, you can use a similar typedef
trick with pointers to blocks.
Calling an objective c method using a function pointer from a c++ method
The problem is that the function signature of Objective-C methods is not as simple as you might think.
In order to make object-oriented programming possible, Objective-C methods take two implicit arguments: id self, SEL _cmd
, the calling object and the selector sent - these need to be passed. You will need to get an object to call the method on, and you should store the selector too. Then, change your function type definition to the correct one:
typedef void (*FuncPtr) (id, SEL, status);
To be read: [1], [2] (near the part typedef id (*IMP)(id, SEL, ...)
)
Converting a function pointer to a block in objective-C
why not just have a simple function
typedef void (*DummyAction)(char * result);
typedef void (^DummyBlock)(char * result);
DummyBlock functionToBlock(DummyAction func) {
return [[^(char * result) {
func(result);
} copy] autorelease];
}
Globally declaring a function pointer in Objective C
The name is in the wrong place:
@interface GetStatusUpdate : NSObject
{
void (^completionHandler)(UIBackgroundFetchResult);
}
Then, some where, you have to define the block:
completionHandler = ^(UIBackgroundFetchResult result) {
// do your work
};
or assign it as you did.
I find this helpful when I have to work with blocks: http://fuckingblocksyntax.com/
As an aside, your block is being stored as an instance variable, not a global variable.
Objective-c function pointer
If you know the method in advance:
[self performSelector:@selector(myMethod) withObject:nil];
If you don't know the method name in advance:
SEL selector = NSSelectorFromString(someSelectorStringYoureGiven);
[self performSelector:selector withObject:nil];
Both these examples assume your function accepts no arguments, nor requires execution on a different thread, nor requires delayed execution. There are many variants for all combinations of those conditions (and NSInvocation for even more complex cases). Search performSelector
in xcode's documentation to see all the variants.
Function pointer to objc class member method, for use in C++?
"Function pointer" is not possible here, because you can't use a function pointer to call an instance method (unless you pass around the instance with the function pointer).
You can create a callable object, however.
struct Callback {
MyViewControllerClass *instance;
void operator()() {
[instance objcCallback];
}
};
You could also use a C++ lambda, which is vaguely equivalent.
Related Topics
What Is Activation Record in the Context of C and C++
How to Write a Stateful Allocator in C++11, Given Requirements on Copy Construction
Ad Hoc Polymorphism and Heterogeneous Containers with Value Semantics
How to Use Memcpy in C++ to Copy Classes That Have No Pointers or Virtual Functions
Is 'Bool' a Basic Datatype in C++
Why Do We Use Std::Function in C++ Rather Than the Original C Function Pointer
Where in Memory Is Vtable Stored
Portable Compare and Swap (Atomic Operations) C/C++ Library
Std::Enable_If:Parameter VS Template Parameter
How to Implement Lock Free Map in C++
Default Visibility of C++ Class/Struct Members
How to Iterate Over a Constant Vector
C++ Object Created with New, Destroyed with Free(); How Bad Is This
How to Erase & Delete Pointers to Objects Stored in a Vector
Why Does Unique_Ptr Take Two Template Parameters When Shared_Ptr Only Takes One
How to Find the Name of the Calling Function
C++11 Range-Based For-Loop Efficiency "Const Auto &I" Versus "Auto I"
Getline Keeps on Getting Newline Character. How to Avoid This