如何将GoLang与React Native对接?JNI函数无法解析问题求助
解决React Native调用Go函数时的JNI函数找不到问题
你遇到的Cannot resolve corresponding JNI function Java_com_wgrn_WGRNNativeModule_Connect错误,核心原因是Go编译生成的C共享库导出的函数名,和Android JNI要求的命名规范不匹配,同时Go函数的参数、返回值也没有按照JNI规则处理。下面是具体的解决步骤:
1. 修改Go代码,适配JNI规范
Go通过c-shared模式编译时,导出的函数名需要严格遵循JNI的命名格式:Java_<包名>_<类名>_<方法名>(包名中的.要换成_),同时要处理JNI的参数和Java对象的类型转换。修改后的Go代码如下:
package main /* #include <jni.h> #include <stdlib.h> */ import "C" import "fmt" import "unsafe" // 用//export指定和JNI期望完全一致的函数名 // 对应Android端com.wgrn.WGRNNativeModule类的Connect方法 //export Java_com_wgrn_WGRNNativeModule_Connect func Java_com_wgrn_WGRNNativeModule_Connect(env *C.JNIEnv, clazz C.jobject, config *C.char) C.jobjectArray { // 将C字符串转成Go字符串 goConfig := C.GoString(config) var resultArr C.jobjectArray // 执行原有Connect逻辑 isConnected, err := Connect(goConfig) // 获取Java类,用于创建对象数组 booleanClass := C.FindClass(*env, C.CString("java/lang/Boolean")) stringClass := C.FindClass(*env, C.CString("java/lang/String")) objectClass := C.FindClass(*env, C.CString("java/lang/Object")) // 创建长度为2的Object数组(对应返回的bool值和错误信息) resultArr = C.NewObjectArray(*env, 2, objectClass, nil) // 填充第一个元素:Boolean对象 boolConstructor := C.GetMethodID(*env, booleanClass, "<init>", "(Z)V") boolObj := C.NewObject(*env, booleanClass, boolConstructor, C.jboolean(isConnected)) C.SetObjectArrayElement(*env, resultArr, 0, boolObj) // 填充第二个元素:错误信息或空字符串 var msg *C.char if err != nil { msg = C.CString(err.Error()) } else { msg = C.CString("") } strObj := C.NewStringUTF(*env, msg) C.SetObjectArrayElement(*env, resultArr, 1, strObj) // 释放C字符串内存,避免泄漏 C.free(unsafe.Pointer(msg)) return resultArr } // 原有Connect逻辑保持不变 func Connect(config string) (bool, error) { if config == "" { return false, fmt.Errorf("config is not available") } return true, nil } func main() {}
2. 交叉编译Go库到Android架构
直接用go build默认编译的是当前主机架构的库,Android无法使用,需要指定对应Android的架构参数编译:
编译arm64架构(主流Android设备)
GOOS=android GOARCH=arm64 go build -o libpackage.so -buildmode=c-shared package.go
编译arm32架构
GOOS=android GOARCH=arm GOARM=7 go build -o libpackage.so -buildmode=c-shared package.go
编译完成后,将libpackage.so放到Android项目的src/main/jniLibs/<架构>/目录下(比如arm64-v8a)。
3. 验证Android NativeModule的方法签名
确保你的NativeModule类的包名、类名和JNI函数名完全对应:
- 包名:
com.wgrn - 类名:
WGRNNativeModule - native方法声明:
private native Object[] Connect(String config);
这样JNI就能正确找到对应的Go导出函数了。
额外注意事项
- Go代码中涉及JNI的操作要严格遵循JNI规范,比如内存释放、类和方法ID的获取
- 如果遇到类找不到的错误,检查JNI中
FindClass的参数是否正确(比如java/lang/Boolean不要写错) - 测试时确保设备架构和编译的库架构一致
内容的提问来源于stack exchange,提问作者Srinath Baride
相关产品推荐
相关产品推荐

