Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You have a few options.</p> <h1>Using blocks</h1> <p>You may use blocks to convey your callback work. This is probably the simplest solution as it allows you to call your code without having to pass any parameter to the callback "function". Blocks work in C and all its supersets with Clang, and Clang++ even allows implicit casts between blocks and lambdas.</p> <pre><code>#include &lt;dispatch/dispatch.h&gt; void setup_callback(dispatch_block_t block) { // required to copy the block to the heap, otherwise it's on the stack dispatch_block_t copy = [block copy]; // setup stuff here // when you want to call the callback, do as if it was a function pointer: // block(); } int main() { MyClass* instance = [[MyClass alloc] init]; setup_callback(^{ [instance callback_method]; }); } </code></pre> <p>That might require some reworking on the C++ end to accept functors (or just blocks if it's simpler) instead of function pointers.</p> <p>Since blocks create closures, they're very convenient for that kind of works.</p> <p>Blocks are an Apple extension to C, C++ and Objective-C. See more about them <a href="http://thirdcog.eu/pwcblocks/">here</a>.</p> <h1>Use the Objective-C runtime to acquire the function pointer to the method you want to call</h1> <p>Use the Objective-C runtime to access the function pointer of your selector. This is more tedious and requires you to keep track of three variables (the object to call the method on, the selector to use, and the method implementation), but it actually works even in the case you can't use the Objective-C syntax.</p> <p>Objective-C method implementations are function pointers with this signature:</p> <pre><code>typedef void (*IMP)(id self, SEL _cmd, ...); </code></pre> <p>Where <code>self</code> is what you'd expect, <code>_cmd</code> is the selector that caused this method call (the <code>_cmd</code> variable is actually available in all Objective-C methods, try it), and the rest is considered variadic. You <strong>need</strong> to cast <code>IMP</code> variables into the proper function signature because the calling convention for variadic C functions doesn't always match the calling convention for Objective-C method calls (the Objective-C method call is the standard function calling convention for your compiler, probably either <code>cdecl</code> or the amd64 calling convention, and the variadic calling convention is <em>not always</em> the same). A <code>reinterpret_cast</code> will be able to do it.</p> <p>Here's some code I put together for similar intents. It uses C++11 variadic templates to help with getting the proper function signature.</p> <pre><code>#include &lt;objc/runtime.h&gt; template&lt;typename TReturnType, typename... TArguments&gt; auto GetInstanceMethodPointer(Class class, SEL selector) -&gt; TReturnType (*)(id, SEL, TArguments...) { Method m = class_getInstanceMethod(class, selector); IMP imp = method_getImplementation(m); return reinterpret_cast&lt;TReturnType (*)(id, SEL, TArguments...)&gt;(imp); } int main() { MyClass* instance = [[MyClass alloc] init]; auto foo = GetInstanceMethodPointer&lt;void&gt;( [MyClass class], @selector(my_callback)); // foo is a void (*)(id, SEL) function pointer foo(instance, @selector(my_callback)); } </code></pre> <p>Also take care that your instance is not <code>nil</code> before using the function call, because <code>nil</code> checking is handled by the Objective-C runtime. In this case, we're bypassing it.</p> <h1>Keep track of an object and a <code>SEL</code></h1> <p>Use <code>-[NSObject performSelector:]</code> to perform your callback. Basically a simpler version of the Objective-C runtime solution.</p> <pre><code>void setup_callback(id object, SEL selector) { // do stuff // to execute the callback: // [object performSelector:selector]; } int main() { MyClass* instance = [[MyClass alloc] init]; setup_callback(instance, @selector(my_callback)); } </code></pre> <h1>Wrapping your call inside a C++ function</h1> <p>I think this one doesn't really need any example. Create a function that accepts your object type as the first parameter and call the method you want on it. Similarly to the <code>SEL</code> solution, you then need to separately keep track of the function to call and the object on which to call it.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload