1 静态注册的方式实现c/c++和java相互调用
C/C++中访问Java方法
C/C++中访问Java父类的方法
C/C++中访问/修改Java变量
Java中访问C/C++方法
Java中访问/修改C/C++变量
给出实现代码如下:
// StaticReg.java
package com.android.javacpp;
import android.util.Log;
public class StaticReg {
private String TAG = "JC_StaticReg";
private String TestString = "1234";
private int TestInt = 1234;
// java access c++
public native String geJNIString();
public native int getJNIInt(Object obj);
public native void passStringToJNI(String str);
// 用于调用 C++ 方法
public native int callJNIAdd(int a, int b);
// c++ access java
public native void setJavaString();
public native void setJavaInt();
public native int callJavaMethodAdd();
public int Add(int a, int b) {
return a + b;
}
public void StaticRegTest()
{
Log.d(TAG, "geJNIString: " + geJNIString());
Log.d(TAG, "getJNIInt: " + getJNIInt(this));
passStringToJNI("12345678");
int result = callJNIAdd(999, 999);
Log.d(TAG, "callNativeAdd: " + result);
// c++ access java
Log.d(TAG, "before modif TestString: " + TestString);
setJavaString();
Log.d(TAG, "after modif TestString: " + TestString);
Log.d(TAG, "before modif TestInt: " + TestInt);
setJavaInt();
Log.d(TAG, "after modif TestInt: " + TestInt);
int result2 = callJavaMethodAdd();
Log.d(TAG, "callJavaMethodAdd: " + result2);
}
}
StaticReg.cpp
#include <jni.h>
#include <string>
#include "log.h"
#include "DynamicReg.h"
extern "C"
JNIEXPORT jstring JNICALL
Java_com_android_javacpp_StaticReg_geJNIString(JNIEnv *env, jobject thiz) {
// TODO: implement geJNIString()
return env->NewStringUTF("the string from C++");
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_android_javacpp_StaticReg_getJNIInt(JNIEnv *env, jobject thiz, jobject obj) {
// TODO: implement getJNIInt()
jint inttest = 999;
return inttest;
}
extern "C"
JNIEXPORT void JNICALL
Java_com_android_javacpp_StaticReg_passStringToJNI(JNIEnv *env, jobject thiz, jstring str) {
// TODO: implement passStringToJNI()
const char* utfChars = env->GetStringUTFChars(str, nullptr);
std::string strtest = utfChars;
LOGD("string from java: %s", strtest.c_str());
env->ReleaseStringUTFChars(str, utfChars);
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_android_javacpp_StaticReg_callJNIAdd(JNIEnv *env, jobject thiz, jint a, jint b) {
// TODO: implement callJNIAdd()
return a + b;
}
extern "C"
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
jint result = DynamicReg::GetInstance().RegisterNatives(env);
LOGD("RegisterNatives result: %d", result);
return JNI_VERSION_1_6;
}
// c++ access java method/var
extern "C"
JNIEXPORT void JNICALL
Java_com_android_javacpp_StaticReg_setJavaString(JNIEnv *env, jobject thiz) {
// TODO: implement setJavaString()
jclass activityClass=env->GetObjectClass(thiz);
// 获取java层的text属性
jfieldID idText = env->GetFieldID(activityClass, "TestString", "Ljava/lang/String;");
//给text属性赋值
jstring text1 = env->NewStringUTF("5678");
env->SetObjectField(thiz, idText, text1);
// 通过jobject参数获取MainActivity对应的class对象在Native层的映射jclass 对象
// 通过jclass 对象得到text属性的id
// 通过text属性id去修改text的值
}
extern "C"
JNIEXPORT void JNICALL
Java_com_android_javacpp_StaticReg_setJavaInt(JNIEnv *env, jobject thiz) {
// TODO: implement setJavaInt()
jclass activityClass=env->GetObjectClass(thiz);
// 获取java层的text属性
jfieldID idText = env->GetFieldID(activityClass, "TestInt", "I");
//给text属性赋值
jint text1 = 5678;
env->SetIntField(thiz, idText, text1);
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_android_javacpp_StaticReg_callJavaMethodAdd(JNIEnv *env, jobject thiz) {
// TODO: implement callJavaMethodAdd()
// 获取 MainActivity 类的引用
jclass clazz = env->FindClass("com/android/javacpp/StaticReg");
if (clazz == nullptr) {
return -1;
}
// 获取 MainActivity 实例的引用
jobject activityObj = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
if (activityObj == nullptr) {
return -1;
}
// 调用 MainActivity 中的 add 方法
jmethodID addMethodId = env->GetMethodID(clazz, "Add", "(II)I");
if (addMethodId == nullptr) {
return -1;
}
return env->CallIntMethod(activityObj, addMethodId, 100, 20);
}
2 动态注册的方式实现c/c++调用java的方法/变量
C/C++中访问Java方法
C/C++中访问Java父类的方法
C/C++中访问/修改Java变量
Java中访问C/C++方法
Java中访问/修改C/C++变量
// DynamicReg.java
package com.android.javacpp;
import android.util.Log;
public class DynamicReg {
private String TAG = "JC_DynamicReg";
public native String stringFromJNI();
public static native int add(int a, int b);
public int JavaInt = 10;
public void JavaMethod() {
// System.out.println("Hello from Java!");
Log.d(TAG, "Java print hello world");
}
public native void JNIMethod();
public void DynamicRegTest()
{
Log.d(TAG, "stringFromJNI: " + stringFromJNI());
Log.d(TAG, "add (100, 500) " + add(100,500));
Log.d(TAG, "JNIMehod called");
JNIMethod();
}
}
// DynamicReg.cpp
//
// Created by Administrator on 2023/7/6.
//
#include "DynamicReg.h"
std::string DynamicReg::myString = "Hello from c++";
jstring DynamicReg::stringFromJNI(JNIEnv *env, jobject instance) {
jint version = env->GetVersion();
LOGD("JNI version is : %x", version);
return env->NewStringUTF(myString.c_str());
}
jint DynamicReg::JNIadd(JNIEnv *env, jclass clazz, jint a, jint b) {
return a + b;
}
jint DynamicReg::RegisterNatives(JNIEnv *env) {
jclass clazz = env->FindClass("com/android/javacpp/DynamicReg");
if (clazz == NULL) {
LOGE("could't find class: com/android/javacpp/DynamicReg");
return JNI_ERR;
}
JNINativeMethod methods_MainActivity[] = {
{
"stringFromJNI", "()Ljava/lang/String;", (void *) stringFromJNI},
{
"add", "(II)I", (void *) JNIadd},
{
"JNIMethod", "()V", (void*) JNIMethod}
};
// int len = sizeof(methods_MainActivity) / sizeof(methods_MainActivity[0]);
return env->RegisterNatives(clazz, methods_MainActivity,
sizeof(methods_MainActivity) / sizeof(methods_MainActivity[0]));
}
jint DynamicReg::JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
LOGE("JNI_ERR");
return JNI_ERR;
}
jint result = RegisterNatives(env);
LOGD("RegisterNatives result: %x", result);
return JNI_VERSION_1_6;
}
DynamicReg& DynamicReg::GetInstance()
{
static DynamicReg instance;
return instance;
}
void DynamicReg::JNIMethod(JNIEnv *env, jobject obj)
{
// 访问Java层的变量
jfieldID fieldId = env->GetFieldID(env->GetObjectClass(obj), "JavaInt", "I");
jint myInt = env->GetIntField(obj, fieldId);
printf("myInt = %d\n", myInt);
LOGD("C++ get JavaInt = %d\n", myInt);
// 调用Java层的方法
jmethodID methodId = env->GetMethodID(env->GetObjectClass(obj), "JavaMethod", "()V");
env->CallVoidMethod(obj, methodId);
}
完整示例代码下载
JNI实现java cpp相互调用