DEV Community

Andrei Xavier de Oliveira Calazans
Andrei Xavier de Oliveira Calazans

Posted on

5

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

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

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

Sentry growth stunted Image

If you are wasting time trying to track down the cause of a crash, it’s time for a better solution. Get your crash rates to zero (or close to zero as possible) with less time and effort.

Try Sentry for more visibility into crashes, better workflow tools, and customizable alerts and reporting.

Switch Tools

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay