Skip to content

The C++ Turbo Module template uses a Kotlin implementation on Android #829

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 of 2 tasks
Zach-Dean-Attractions-io opened this issue Apr 24, 2025 · 7 comments
Open
1 of 2 tasks
Labels
bug Something isn't working

Comments

@Zach-Dean-Attractions-io

Description

I'm not sure if I'm missing something obvious but when creating the library template for a Turbo Module using C++ for Android & iOS there is a default example implementing a multiply function. However, on Android the implementation for this function is in Kotlin and it doesn't use the shared C++ library.

When the JS code calls multiply it comes into the code here.

Is there any reason why the OnLoad.cpp file isn't used to register the turbo module in this case as described here: pure-cxx-modules#android

Packages

  • create-react-native-library
  • react-native-builder-bob

Selected options

  1. npx create-react-native-library cppLibraryTest
  2. ? What is the name of the npm package? › cpp-lib-test
  3. ? What type of library do you want to develop? › Turbo Module
  4. ? Which languages do you want to use? › C++ for Android & iOS

Link to repro

N/A

Environment

System:
  OS: macOS 15.0.1
  CPU: (11) arm64 Apple M3 Pro
  Memory: 90.06 MB / 18.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 23.7.0
    path: /opt/homebrew/bin/node
  Yarn:
    version: 3.6.1
    path: /opt/homebrew/bin/yarn
  npm:
    version: 11.2.0
    path: /opt/homebrew/bin/npm
  Watchman:
    version: 2025.02.17.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.16.2
    path: /opt/homebrew/opt/ruby/bin/pod
@Zach-Dean-Attractions-io Zach-Dean-Attractions-io added the bug Something isn't working label Apr 24, 2025
@Zach-Dean-Attractions-io
Copy link
Author

I think the fix is relatively straightforward to call the native multiply implementation from the Kotlin implementation

package com.cpplibtest

import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.annotations.ReactModule

@ReactModule(name = CppLibTestModule.NAME)
class CppLibTestModule(reactContext: ReactApplicationContext) :
  NativeCppLibTestSpec(reactContext) {

  override fun getName(): String {
    return NAME
  }

  // Example method
  // See https://reactnative.dev/docs/native-modules-android
  override fun multiply(a: Double, b: Double): Double {
-   return a * b
+   return nativeMultiply(a, b)
  }

  companion object {
    const val NAME = "CppLibTest"

+   @JvmStatic
+   external fun nativeMultiply(a: Double, b: Double): Double

+   init {
+     System.loadLibrary("cpp-lib-test")
+   }
  }
}

I think it should be possible to use a pure C++ implementation as described here though whereas this methodology is more of a Kotlin implementation which calls into shared C++ code using the JNI. I'll try take a look into this.

@Zach-Dean-Attractions-io
Copy link
Author

Zach-Dean-Attractions-io commented Apr 25, 2025

Oh I see this template has been removed: #818

Is there any plan to support a pure C++ module template in the future? With React Native 0.79.0 there is a way to register pure C++ modules via the codegen spec, so I think this should allow for a pure C++ self contained library implementation.

@satya164
Copy link
Member

satya164 commented Apr 25, 2025

Is there any plan to support a pure C++ module template in the future

I haven't managed to write a C++ library that works. The official docs only cover how to write one in existing app, https://reactnative.dev/docs/the-new-architecture/pure-cxx-modules, but trying to use same approach with a library doesn't seem to work with autolinking.

If you figure out how then PR or a sample library I can turn into a template is welcome.

@Zach-Dean-Attractions-io
Copy link
Author

I did manage to get iOS working by adding code to the consuming app's AppDelegate file to register the module. I think React Native 0.79.0 released something in the codegen process to declare your native modules and it would link them for you but I ran into a crash when trying this. I asked in the reactwg repo here about it: reactwg/react-native-new-architecture#286

However, I stumbled across this youtube video https://www.youtube.com/watch?v=KURIqiCPbco and they used an Objective-C file in the library and registered the native module in the + (void) load function.

#import <Foundation/Foundation.h>
#import "MyCpp.h"
#import <ReactCommon/CxxTurboModuleUtils.h>


@interface OnLoad : NSObject
@end

@implementation OnLoad

using namespace facebook::react;

+ (void) load {
  registerCxxModuleToGlobalModuleMap(
    std::string(MyCpp::kModuleName),
    [](std::shared_ptr<CallInvoker> jsInvoker) {
      return std::make_shared<MyCpp>(jsInvoker);
    }
  );
}

@end

This is working for me. I'm going to watch the Android version next and try implementing that. If I get both working I'll either share a repo or create a PR (if time allows).

I'll also ask in the reactwg repo to check this is best practise.

@Zach-Dean-Attractions-io
Copy link
Author

Zach-Dean-Attractions-io commented Apr 28, 2025

Ok I have Android working too thanks to the author's other video https://www.youtube.com/watch?v=ibgHObp8YwA&t=8s

This repo has the changes for Android & iOS react-native-pure-cpp-turbo-module-library. If I get time I could attempt a PR to add it into the create-react-native-library project, but I also might wait for a review from the RN team to check this is best practice and if there are any mistakes that I have made or other problems this solution may cause.

@satya164
Copy link
Member

@Zach-Dean-Attractions-io thank you! i'll check it out

@satya164
Copy link
Member

satya164 commented May 3, 2025

@Zach-Dean-Attractions-io I was able to setup a sample with the latest template based on your example https://github.com/satya164/react-native-pure-cpp-turbo-module-library

However, before we can include it as a template, we would want to disable includeGeneratedCode, and while it works on iOS, it doesn't seem to work on Android.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants