JSI绑定Native模块时为什么拿不到正确的方法?
我用JSI写了个Native模块,在C++层注册了函数,但JS端调用时报错说方法不存在。明明名字对上了,也重新编译了,还是不行。
我试过在installJSIBindings里打印日志,能进到函数里,但绑定的函数就是没挂到global上。是不是漏了什么步骤?
// jsi-bindings.cpp 里这样注册的
auto testFunc = jsi::Function::createFromHostFunction(
runtime,
jsi::PropNameID::forAscii(runtime, "testFunc"),
0,
[](jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) -> jsi::Value {
return jsi::String::createFromUtf8(rt, "hello from native");
}
);
runtime.global().setProperty(rt, "testFunc", std::move(testFunc));
改一下试试:
或者用 String 的方式更稳:
还有个常见坑:如果你的模块在 iOS 上用 Swift 写的但底层用了 C++ JSI,桥接层可能没正确传递 runtime 对象。这种情况建议直接看 RN 官方那个 NativeModule 的 JSI 示例,代码结构基本是固定的。
如果还不行,打印一下 runtime.global().hasProperty(rt, "testFunc") 看看是不是 setProperty 本身失败了。
新架构下正确的做法是用
jsi::Object创建一个宿主对象,然后用makeNativeBinding绑定:或者更标准的做法是通过TurboModule注册,别直接挂global上。你得确认下:
1. 你是在哪个React Native版本?如果是0.68+,新架构的话得用TurboModule那一套
2. 检查你的C++代码是否链接正确,有时候编译过了但实际没加载到
3. 看看有没有用
RCT_EXTERN_MODULE+RCT_EXTERN_METHOD这套暴露给JS还有个小坑:如果你的函数签名是void返回的,得确保JSI侧和JS侧类型匹配。
你那个打印日志能进到installJSIBindings,说明C++确实执行了,那大概率就是绑定位置或方式的问题。贴一下你完整的注册代码,我看看具体哪儿的写法不对。