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

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more

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

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more