DEV Community

Andrei Xavier de Oliveira Calazans
Andrei Xavier de Oliveira Calazans

Posted on

How to interop between Objective-C and C++?

In the world of cross-platform, it is common for the need to create bridges of communication between different languages. While working with React Native and iOS, I stumbled on a need to interop with a C++ class. This post covers how you can communicate between Objective-C and C++ code.

Using Objective-C++

You can transform your Objective-C file (.m) to Objective-C++ (.mm). This by default enables you to call any C++ code in your Objective-C++ file.

MyObjective_c_file.mm

#include "SomePrivateCppClass.h"

@implementation MyObjective_c_file
- (instancetype) init
{
  // Add your logic here
  SomePrivateCppClass::someMethod();
}

@end

Note - Sometimes you can have issues with this approach especially when your C++ interface is importing code that causes an issue for the Objective-C compiler. To overcome this you can do the next step

Interopping with a C interface to call an Objective-C function from C++

When file separation is required due to external dependencies. You can interop by using a C interface.

C.interface.h

void callFromCpp(const char *dataPayload);

MyObjective_c_file.mm


@implementation MyObjective_c_file
...
 - (void)myMethod: (NSString *) dataPayload {

  // Your logic here
}

@end


void callFromCpp(const char *dataPayload) {
     NSString *convertedString = [[NSString alloc] initWithCString: dataPayload encoding:NSUTF8StringEncoding];

     MyObjective_c_file myInstance = [[MyObjective_c_file alloc] init];
    [MyObjective_c_file myMethod: convertedString];
}

YourCppClass.cpp

YourCppClass::WhatEverMethod() {
  callFromCpp(stringData.c_str());
}

Passing pointers with a C interface to call a C++ method.

When using a C interface, you can also pass a pointer of your C++ class in order to call it from your Objective-C++ code (This is ideal when you can't include your C++ file due to dependencies).

In this case, you will instantiate your Objective-C class by calling a C function from your C++ method, then pass a pointer of your C++ class to your Objective-C interface for it to consume it.

C.interface.h

void initFromCpp(long castBridgePointer);

MyObjective_c_file.mm

#include "YourCppClass.h"

@implementation MyObjective_c_file
static YourCppClass *pointerToBridge;
...
- (void)storeCastBridgePointer: (long) ptr {
    pointerToBridge = (YourCppClass *) ptr;
}

@end

void initFromCpp(long castBridgePointer)
{
     MyObjective_c_file myInstance = [[MyObjective_c_file alloc] init];
    [myInstance storeCastBridgePointer: castBridgePointer];
}

YourCppClass.cpp

YourCppClass::YourCppClass() {
  // whatever logic...

  initFromCpp((long) this);
}

Conclusion

Interop between C++ and Objective-C is not too complicated. The purpose of this post is to bring both solutions, the plain Objective-C approach and C interface approach, into a single post where anyone can reference in the future

Top comments (1)

Collapse
 
brun0oo profile image
Brun0oO

I think the correct "callFromCpp" is :

  void callFromCpp(const char *dataPayload) {
    NSString *convertedString = [[NSString alloc] initWithCString: dataPayload encoding:NSUTF8StringEncoding];
    MyObjective_c_file* myInstance = [[MyObjective_c_file alloc] init];
    [myInstance myMethod: convertedString];
  }
Enter fullscreen mode Exit fullscreen mode