函数返回后 char* 值发生变化

标签 c java-native-interface

没有找到类似的问题,所以打开一个新的。

我试图将一个 Java 对象传递到我程序中的 JNI 层,并在其中提取 Java String 字段。提取的字段设置在 C 结构中。

我看到了一个奇怪的行为。我能够成功提取所需的字段并将其存储在结构字段中。但是当我的效用函数返回时,结构中设置的字段被破坏了。 我怀疑内存泄漏并重新检查,但看起来没有任何可疑之处(我没有做太多动态内存代码......只有一个 malloc 和 free。)

代码如下:

头文件:

typedef struct Job {
   char* job_id;
} Job;

C 文件:

JNIEXPORT jint JNICALL Java_com.test.JobHandler__1submitJob(
        JNIEnv *env, jobject this, jobject job) {       
    current_job = (Job *) malloc(sizeof(Job));
    convert_job(env, job, current_job);
    free(current_job);
}

void convert_job(JNIEnv *env, jobject javajob, Job *job) {
    jclass cls = (*env)->GetObjectClass(env, javajob);    
    getVoidStringField(env, cls, javajob, job->job_id, "getJob_id");
    //job->job_id gets corrupted here
}

void getVoidStringField(JNIEnv *env, jclass cls, jobject obj, char *jobStr, char *methodName) {
    jmethodID mid = (*env)->GetMethodID(env, cls, methodName, "()Ljava/lang/String;");
    jobject js =  (*env)->CallObjectMethod(env, obj, mid);
    const char *str = (*env)->GetStringUTFChars(env, js, 0);
    int len = (*env)->GetStringUTFLength(env, js);
    jobStr = (char*) malloc(len);
    memcpy(jobStr, str, len);
    jobStr[len] = '\0';
    (*env)->ReleaseStringUTFChars(env, js, str);
    //jobStr is fine till here.
}

我从我的代码中删除了其他东西并降低到上面的版本以简单地调试,仍然是同样的问题。

如果我稍微修改 getVoidStringField(...) 以接受 Job 对象,然后处理 job->job_id,它工作正常。

很想知道。我怀疑它与 JNI 有什么关系。

最佳答案

一些事情:
当你传入 job->job_id ,您传递的是该指针的 VALUE,而不是指针本身。这意味着当你执行 jobStr = (char*) malloc(len); , 你没有改变 job->job_id ,但只是该函数的局部变量。

所以,你需要传入的是&(job->job_id) , 参数应为 char **jobstr

你的 malloc然后将是(不要忘记允许空终止符):

*jobStr = (char*) malloc(len +1);

当然,下面的语句应该引用*jobstr

关于函数返回后 char* 值发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29454107/

相关文章:

C 转换说明符

c++ - C中的这些声明有什么区别?

c - 是否可以在c中将函数作为参数传递?

一个函数可以返回两个值吗?

java - 使用 Foundation NSLock 在 JNI 中互斥

java - 从 C++ 启动时正确关闭 JVM

c - 使用 OpenMP 和 mpz_t malloc 导致段错误

android - 使用 ndk-build 编译时找不到 OpenCV header

java - 附加到已经运行的 JVM

java - 为什么 sun.misc.Unsafe.unpark() 被描述为 'Unsafe' ?