Cocos2d-x 中如何使用jni Java 调用 C++
之前我们介绍过在 Cocos2d-x 中如何使用 JNI 实现 C++ 调用 Java,今天我们将探讨相反的情况,即如何在 Java 中调用 C++。
1. 加载共享库
在 Cocos2d-x 里,C++ 代码会被编译成一个 .so 文件,该文件会被放置在安卓目录下的 libs/armeabi 中,随后 Java 会将其加载进来。不过,这一步我们无需手动操作,因为 Cocos2d-x 已经为我们处理好了。
2. Java 代码实现
以下是 Java 代码的示例:
package cb.CbCCBLE;
public class CbCCBLECentralManager {
public static final String TAG = "CbCCBLECentralManager Android";
public native static void bleCenterManagerNotificationChangeState(int oldState, int newState);
public native static void bleCenterManagerNotificationDidScanOnePeripheral(String peripheralId);
public native static void bleCenterManagerNotificationDidFinishScanning();
}
在 Java 中,我们只是定义了几个 native 方法。在 Java 代码里调用这些方法时,实际执行的是对应的 C++ 代码。接下来,我们重点关注 C++ 代码的实现,这里以刚刚定义的三个方法为例进行说明。
3. C++ 代码实现
extern "C" {
// 处理状态变化通知
void Java_cb_CbCCBLE_CbCCBLECentralManager_bleCenterManagerNotificationChangeState(JNIEnv* env, jobject thiz, jint oldState, jint newState) {
CCLOG("Java_cb_CbCCBLE_CbCCBLECentralManager_bleCenterManagerNotificationChangeState");
CCLOG("oldState:%d, newState:%d", (int)oldState, (int)newState);
}
// 处理扫描到一个外设的通知
void Java_cb_CbCCBLE_CbCCBLECentralManager_bleCenterManagerNotificationDidScanOnePeripheral(JNIEnv* env, jobject thiz, jstring peripheralId) {
CCLOG("Java_cb_CbCCBLE_CbCCBLECentralManager_bleCenterManagerNotificationDidScanOnePeripheral");
std::string peripheralIdStr = JniHelper::jstring2string(peripheralId);
CCLOG("%s", peripheralIdStr.c_str());
}
// 处理扫描完成的通知
void Java_cb_CbCCBLE_CbCCBLECentralManager_bleCenterManagerNotificationDidFinishScanning(JNIEnv* env, jobject thiz) {
CCLOG("Java_cb_CbCCBLE_CbCCBLECentralManager_bleCenterManagerNotificationDidFinishScanning");
}
}
需要注意的是,我们的 C++ 代码都写在 extern "C" 块中。C++ 方法的命名有特定的格式:以 Java 开头,接着是包名、类名和方法名,它们之间用 _ 分隔,传入的参数紧跟在后面。关于 JNI 数据类型到 C++ 数据类型的转换,这里就不详细展开了。
通过以上步骤,我们就实现了在 Cocos2d-x 中使用 JNI 让 Java 调用 C++ 的功能。