Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C代码需要调用Java代码缓冲区,但无法获取其JNIEnv_Java_Android_C_Jvm Crash_Jnienv - Fatal编程技术网

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

C代码需要调用Java代码缓冲区,但无法获取其JNIEnv,java,android,c,jvm-crash,jnienv,Java,Android,C,Jvm Crash,Jnienv,我有一个java缓冲区,需要对其进行一些c数据操作。 为此,我调用了一个本机函数“SimpleFunction”,它调用java代码来检索特定索引处的缓冲区值(buffer\u read\u byte)并保存修改后的值(buffer\u byte\u write) Java端: byte buffer = new byte[100]; public static byte getByte(int index) { return buffer[index]; } public sta

我有一个java缓冲区,需要对其进行一些c数据操作。 为此,我调用了一个本机函数“SimpleFunction”,它调用java代码来检索特定索引处的缓冲区值(buffer\u read\u byte)并保存修改后的值(buffer\u byte\u 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);
#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;
}   
byte buffer=新字节[100];
公共静态字节getByte(int索引){
返回缓冲区[索引];
}   
公共静态void writeByte(int-in,int-index){
缓冲区[索引]=(字节)(in);
}
私有本机void SimpleFunction(int-size);
对于(int i=0;iFindClass(env,“com/App/Class”);
如果((*env)->例外检查(env)){
返回0;
}
jmethodID方法=(*env)->GetStaticMethodID(env,cls,“getByte”,“I)B”);
如果((*env)->例外检查(env)){
返回0;
}
jbyte result=(*env)->CallStaticByteMethod(env、cls、method、pos);
如果((*env)->例外检查(env)){
返回0;
}
值=(uint8_t)结果&0xFF;
如果(cls!=NULL)
{
(*env)->DeleteLocalRef(env,cls);
如果((*env)->例外检查(env)){
返回0;
}
}
返回值;
}
无效缓冲区字节写入(JNIEnv*env、jobject this、jint pos、jint数据)
{
int值=数据&0xFF;
jclass cls=(*env)->FindClass(env,“com/App/Class”);
如果((*env)->例外检查(env)){
返回;
}
jmethodID方法=(*env)->GetStaticMethodID(env,cls,“writeByte”,“II)V”);
如果((*env)->例外检查(env)){
返回;
}
(*env)->CallStaticVoidMethod(env、cls、method、value、pos);
如果((*env)->例外检查(env)){
返回;
}
如果(cls!=NULL)
{
(*env)->DeleteLocalRef(env,cls);
如果((*env)->例外检查(env)){
返回;
}
}
返回;
}   
上面的代码有效

现在让我们假设数据操作是由许多内部函数实现的,这些函数在内核中使用c函数buffer\u read\u byte和buffer\u byte\u write。 如何避免在每个调用函数级别显式传递为输入(JNIEnv*env,jobject this)

我有很多预先存在的函数,它们最终需要使用buffer\u read\u byte和buffer\u byte\u write访问java缓冲区。 我如何避免在每个预先存在的父函数和子函数中必须声明输入(JNIEnv*env,jobject this),因为JNIEnv只在内核函数buffer\u read\u byte和buffer\u byte\u write中需要

我检查了全局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;
}   
void Java\u com\u App\u SimpleFunction(JNIEnv*env,jobject this,jint size)
{
(*env)->GetJavaVM(env和jvm);
int地址=0;
对于(address=0;addressGetEnv(jvm,(void**)和env,JNI_版本1_4);
JavaVMAttachArgs args;
args.version=JNI\u version\u 1\u 6;//选择您的JNI版本
args.name=NULL;//您可能希望为java线程指定一个名称
args.group=NULL;//您可能希望将java线程分配给线程组
jint rs=(*jvm)->AttachCurrentThread(jvm,(void**)和env以及args);
//...
返回值;
}
uint8缓冲区字节写入(jint pos、jint数据)
{
JNIEnv*env;
jintrs=(*jvm)->GetEnv(jvm,(void**)和env,JNI_版本1_4);
JavaVMAttachArgs args;
args.version=JNI\u version\u 1\u 6;//选择您的JNI版本
args.name=NULL;//您可能希望为java线程指定一个名称
args.group=NULL;//您可能希望将java线程分配给线程组
jint rs=(*jvm)->AttachCurrentThread(jvm,(void**)和env以及args);
//...
返回;
}   
但是调用SimpleFunction(100)没有执行(我没有对缓冲区进行数据修改),并且在尝试执行GetEnv或者AttachCurrentThread时,会使应用程序崩溃


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

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

对于无法获取JNIenv的C代码来说,调用JAVA代码的最佳方法是什么?给它一种获取env的方法。如果由于某种奇怪的原因无法做到这一点,您需要编写一个可以访问它的代理函数,复制实际函数需要的数据,调用实际函数,然后根据需要复制回数据。