Hoi allemaal,
Ik zit me inmiddels al uren blind te staren op een gigantisch architectuur-probleem en ik hoop dat hier wat RN/C++ goeroes rondhangen. Ik probeer een custom C++ JSI engine in te laden in een React Native project.
Voor de context: ik draai op Expo SDK 52 met React Native 0.81. De New Architecture en Bridgeless mode staan dus standaard aan. Mijn doel is simpelweg een eigen C++ module via JSI direct aan de JavaScript runtime te knopen.
Na veel bloed, zweet en tranen compileert de C++ kant nu eindelijk foutloos via Ninja/Clang. Maar zodra ik de app opstart in de Android emulator, klapt hij er direct uit met een rood scherm vanuit de JS-laag:
[runtime not ready]: Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'PlatformConstants' could not be found. Verify that a module by this name is registered in the native binary.
Voordat jullie met de standaard "heb je je cache geleegd" komen, hier is wat ik allemaal al heb geprobeerd. Eerst probeerde ik een losse library te maken, maar RN 0.81 Bridgeless eist blijkbaar dat alles via één centraal punt gaat.
Dus ben ik de officiële RN docs gaan volgen: alles in appmodules stoppen. In mijn CMakeLists.txt gebruik ik nu project(appmodules) en voeg ik mijn sources toe via target_sources. Zelfs een oude C-file netjes geïsoleerd met C99 flags om C++20 gezeik te voorkomen. Dit compileert dus perfect tot één libappmodules.so.
Omdat ik in appmodules zit, moest ik ook JNI_OnLoad overschrijven in een custom OnLoad.cpp. Ik heb alle RN 0.81 breaking changes netjes doorgevoerd. Dus rncore.h vervangen door FBReactNativeSpec.h, fbjni::initialize gebruikt, en de nieuwe signature van autolinking_ModuleProvider zonder jsInvoker. Mijn eigen JSI install functie roep ik daar ook aan.
Aan de Kotlin kant in de MainActivity laad ik netjes System.loadLibrary("appmodules") en luister ik via de ReactHost naar de context om nullpointers te voorkomen.
En ja, ik heb echt alles nucleair gecleared. gradlew clean, handmatig de build en .cxx mappen weggegooid, expo start -c voor de metro cache, en zelfs de app volledig via adb uninstall van de emulator gegooid om oude bundels uit te sluiten. Maakt niks uit, de PlatformConstants error blijft.
Mijn theorie nu is dat Expo onder water zijn eigen magie doet met appmodules om hun core TurboModules te registreren. Doordat ik de RN docs volg en appmodules en OnLoad.cpp kaap, sloop ik blijkbaar de ongedocumenteerde Expo-initialisatie.
Heeft iemand hier ervaring mee? Hoe injecteer je in hemelsnaam veilig een custom C++ JSI module in een Expo 52 Bridgeless omgeving zonder de interne boel van Expo om zeep te helpen? Moet dit stiekem toch via een losse shared library en heb ik het mis?
Alle ideeën zijn welkom, ik ben er wel even klaar mee voor vandaag haha. Alvast bedankt!
Ik zit me inmiddels al uren blind te staren op een gigantisch architectuur-probleem en ik hoop dat hier wat RN/C++ goeroes rondhangen. Ik probeer een custom C++ JSI engine in te laden in een React Native project.
Voor de context: ik draai op Expo SDK 52 met React Native 0.81. De New Architecture en Bridgeless mode staan dus standaard aan. Mijn doel is simpelweg een eigen C++ module via JSI direct aan de JavaScript runtime te knopen.
Na veel bloed, zweet en tranen compileert de C++ kant nu eindelijk foutloos via Ninja/Clang. Maar zodra ik de app opstart in de Android emulator, klapt hij er direct uit met een rood scherm vanuit de JS-laag:
[runtime not ready]: Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'PlatformConstants' could not be found. Verify that a module by this name is registered in the native binary.
Voordat jullie met de standaard "heb je je cache geleegd" komen, hier is wat ik allemaal al heb geprobeerd. Eerst probeerde ik een losse library te maken, maar RN 0.81 Bridgeless eist blijkbaar dat alles via één centraal punt gaat.
Dus ben ik de officiële RN docs gaan volgen: alles in appmodules stoppen. In mijn CMakeLists.txt gebruik ik nu project(appmodules) en voeg ik mijn sources toe via target_sources. Zelfs een oude C-file netjes geïsoleerd met C99 flags om C++20 gezeik te voorkomen. Dit compileert dus perfect tot één libappmodules.so.
Omdat ik in appmodules zit, moest ik ook JNI_OnLoad overschrijven in een custom OnLoad.cpp. Ik heb alle RN 0.81 breaking changes netjes doorgevoerd. Dus rncore.h vervangen door FBReactNativeSpec.h, fbjni::initialize gebruikt, en de nieuwe signature van autolinking_ModuleProvider zonder jsInvoker. Mijn eigen JSI install functie roep ik daar ook aan.
Aan de Kotlin kant in de MainActivity laad ik netjes System.loadLibrary("appmodules") en luister ik via de ReactHost naar de context om nullpointers te voorkomen.
En ja, ik heb echt alles nucleair gecleared. gradlew clean, handmatig de build en .cxx mappen weggegooid, expo start -c voor de metro cache, en zelfs de app volledig via adb uninstall van de emulator gegooid om oude bundels uit te sluiten. Maakt niks uit, de PlatformConstants error blijft.
Mijn theorie nu is dat Expo onder water zijn eigen magie doet met appmodules om hun core TurboModules te registreren. Doordat ik de RN docs volg en appmodules en OnLoad.cpp kaap, sloop ik blijkbaar de ongedocumenteerde Expo-initialisatie.
Heeft iemand hier ervaring mee? Hoe injecteer je in hemelsnaam veilig een custom C++ JSI module in een Expo 52 Bridgeless omgeving zonder de interne boel van Expo om zeep te helpen? Moet dit stiekem toch via een losse shared library en heb ik het mis?
Alle ideeën zijn welkom, ik ben er wel even klaar mee voor vandaag haha. Alvast bedankt!