1

I don't want to use NSNotification because it is so messing up internally. Is it a way to pass a callback function from C++ to Objective-C++, and let Objective-C call it?

The problem is that I don't know how to pass a function written in C++ to Objective-C++, and how could I use that callback in Objective-C++? Is it a pointer?

I know I can mix them up but my class has to be a C++ class because it inherits some C++ classes.

Patroclus
  • 1,163
  • 13
  • 31
  • Possible duplicate of [Calling C++ from Objective-C](https://stackoverflow.com/questions/19229574/calling-c-from-objective-c) – emsimpson92 Aug 03 '18 at 21:29
  • @emsimpson92 A callback function is not the same as renaming a file to .mm to use C++ in Objective-C... – Patroclus Aug 03 '18 at 21:30
  • Possible duplicate of [From objective C call C++](https://stackoverflow.com/questions/29747337/from-objective-c-call-c) – emsimpson92 Aug 03 '18 at 21:32
  • 2
    @WanhuiQiao Please remember to [be nice](https://stackoverflow.com/help/be-nice). emsimpson is just providing a link to what may be the same question you are asking now. That is not any 'abuse of power'. – TylerH Aug 03 '18 at 21:33
  • 1
    @emsimpson92 I apologize for my unprofessional behavior. – Patroclus Aug 03 '18 at 21:36
  • @FrankJoe Can you provide a piece of code and explain what you are trying to do? It's easier for us to give you a suggestion and for you to understand. – trungduc Aug 04 '18 at 01:26

1 Answers1

1

You're not 100% specific as to the exact use case you're trying to cover here, but I'm going to set out a scenario where this kind of situation occurs, and then show you how to solve it. I hope that will cover your problem too.

So I'm going to assume you have an Objective-C class MyClass with its interface declared in MyClass.h:

@interface MyClass : NSObject
- (void)someMethod;
- (void)otherMethodWhichShouldTakeACallback:?????;
@end

You now have a C++ class MyCPPClass, declared in MyCPPClass.hpp on which you want to pass memberFunction as the callback argument to the otherMethod on MyClass:

class MyCPPClass : public MyBase
{
    void memberFunction();
};

First, we need to figure out the method signature on MyClass. The modern way for callbacks in Objective-C is with Blocks. Blocks work pretty well with Objective-C++, so let's go with that and modify MyClass.h with the following line:

- (void)otherMethodWithBlock:(void(^)(void))callbackBlock;

The calling code will need to reside in an Objective-C++ compilation unit (caller.mm):

void callOtherMemberWithCPP(MyCPPClass* cpp_obj, MyClass* objc_obj)
{
    [objc_obj otherMethodWithBlock:^{
            cpp_obj->memberFunction();
        }];
}

Note that this does not deal with object lifetimes. If you're managing lifetimes on the C++ side with std::shared_ptr, you can use that in your Objective-C++ code too, in which case we might end up with something like:

void callOtherMemberWithCPP(std::shared_ptr<MyCPPClass> cpp_obj, MyClass* objc_obj)
{
    [objc_obj otherMethodWithBlock:^{
            cpp_obj->memberFunction();
        }];
}

In this case, the C++ object will only have its reference count decremented when the Objective-C class is done with the block.

For completeness, the other way to do this would be to use C function pointer syntax. In this case, you would need to declare the Objective-C method along these lines:

- (void)otherMethodWithCallback:(void(*)(void*))callback object:(void*)opaqueCallbackArgument;

And the C++ class's method call would need to be wrapped in a free function or static member function:

void memberFunctionCallback(void* opaque_object)
{
    MyCPPClass* object = static_cast<MyCPPClass*>(opaque_object);
    object->memberFunction
}

…and then call the Objective-C method like this:

    [objc_obj otherMethodWithCallback:memberFunctionCallback object:cpp_obj];

Making this version work nicely with automatic lifetime mechanisms such as shared_ptr is a lot more tricky though.

pmdj
  • 22,018
  • 3
  • 52
  • 103
  • Can I also use this to pass a callback function from Objc to C++? – Patroclus Aug 06 '18 at 17:21
  • Yes, you can use blocks in Objective-C++ and C++ compiled with Apple's compiler. Note that ARC is not enabled by default for C++ compilation units, so you'll either need to enable it explicitly or use `Block_copy` and `Block_release` macros. – pmdj Aug 06 '18 at 18:09