gpt4 book ai didi

java - C代码需要调用Java代码缓冲区但无法获取其JNIEnv

转载 作者:行者123 更新时间:2023-11-30 17:06:55 25 4
gpt4 key购买 nike

我有一个 java 缓冲区,需要对其进行一些 c 数据操作。为此,我调用 native 函数“SimpleFunction”,该函数调用 java 代码来检索特定索引处的缓冲区值 (buffer_read_byte) 并保存修改后的值 (buffer_byte_write)。

Java 端:

byte buffer = new byte[100];
public static byte getByte(int index) {
return buffer[index];
}
public static void writeByte(int in, int index) {
buffer[index] = (byte)(in);
}
private native void SimpleFunction(int size);

for(int i=0;i<100;i++)
setBufferModByteInt(0x55,i);
SimpleFunction(100);

C面:

#include <android/log.h>
#include <jni.h>
#include <string.h>
#include <stdio.h>
#include "algorithms/global.h"
#define LOG_TAG "NDK"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
static JavaVM* jvm;

void Java_com_App_SimpleFunction(JNIEnv * env, jobject this, jint size)
{
int address=0;
for(address=0;address<(int)(size);address++)
{
/*
some data manipulation on ""value""
*/

value=buffer_read_byte(env,this,address)&0xFF;
buffer_byte_write(env,this,address,value);
}
return;
}

uint8_t buffer_read_byte(JNIEnv * env, jobject this, jint pos)
{
uint8_t value=0;
const char * ss="2";
if ((*env)->ExceptionCheck(env)) {
return;
}

jclass cls = (*env)->FindClass(env,"com/App/Class");
if ((*env)->ExceptionCheck(env)) {
return 0;
}
jmethodID method = (*env)->GetStaticMethodID(env, cls, "getByte", "(I)B");
if ((*env)->ExceptionCheck(env)) {
return 0;
}
jbyte result = (*env)->CallStaticByteMethod(env, cls, method,pos);
if ((*env)->ExceptionCheck(env)) {
return 0;
}
value=(uint8_t) result&0xFF;
if(cls!=NULL)
{
(*env)->DeleteLocalRef(env,cls);
if ((*env)->ExceptionCheck(env)) {
return 0;
}
}
return value;
}
void buffer_byte_write(JNIEnv * env, jobject this, jint pos, jint data)
{
int value=data&0xFF;
jclass cls = (*env)->FindClass(env,"com/App/Class");
if ((*env)->ExceptionCheck(env)) {
return;
}
jmethodID method = (*env)->GetStaticMethodID(env, cls, "writeByte", "(II)V");
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, cls, method,value,pos);
if ((*env)->ExceptionCheck(env)) {
return;
}
if(cls!=NULL)
{
(*env)->DeleteLocalRef(env,cls);
if ((*env)->ExceptionCheck(env)) {
return;
}
}
return;
}

上面的代码有效。

现在我们假设数据操作是由许多内部函数完成的,这些函数在内核中使用 C 函数 buffer_read_byte 和 buffer_byte_write。如何避免在每个调用函数级别显式传递作为输入 (JNIEnv * env, jobject this)

我有很多预先存在的函数,最终需要使用 buffer_read_byte 和 buffer_byte_write 访问 java 缓冲区。由于仅在内核函数 buffer_read_byte 和 buffer_byte_write 中需要 JNIEnv,如何避免在每个预先存在的父函数和子函数中必须声明输入 (JNIEnv * env, jobject this)? >

我检查了全局 JVM:

void Java_com_App_SimpleFunction(JNIEnv * env, jobject this, jint size)
{
(*env)->GetJavaVM(env, &jvm);
int address=0;
for(address=0;address<(int)(size);address++)
{
value=buffer_read_byte(address)&0xFF;
/*
some data manipulation on ""value""
*/
buffer_byte_write(address,value);
}
return;
}
uint8_t buffer_read_byte(jint pos)
{
JNIEnv * env;
jint rs=(*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_4);
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6; // choose your JNI version
args.name = NULL; // you might want to give the java thread a name
args.group = NULL; // you might want to assign the java thread to a ThreadGroup
jint rs=(*jvm)->AttachCurrentThread(jvm, (void**)&env, &args);

//...

return value;
}
uint8_t buffer_byte_write(jint pos, jint data)
{
JNIEnv * env;
jint rs=(*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_4);
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6; // choose your JNI version
args.name = NULL; // you might want to give the java thread a name
args.group = NULL; // you might want to assign the java thread to a ThreadGroup
jint rs=(*jvm)->AttachCurrentThread(jvm, (void**)&env, &args);

//...

return;
}

但是调用 SimpleFunction(100) 没有执行(我没有对缓冲区进行数据修改),并且在尝试执行 GetEnvAttachCurrentThread 时导致应用程序崩溃>。

对于无法获取 JNIenv 的 C 代码,调用 JAVA 代码的最佳方法是什么?

最佳答案

也许您需要找出它崩溃的原因。看来您使用的是正确的方法。您还可以查看以下问题的答案。

How to create static JNI Environment Pointer?

How to obtain JNI interface pointer (JNIEnv *) for asynchronous calls

关于java - C代码需要调用Java代码缓冲区但无法获取其JNIEnv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34357906/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com