【问题标题】:Android Java JNI and C Char array Can't recognize the valueAndroid Java JNI和C Char数组无法识别值
【发布时间】:2011-10-31 13:32:07
【问题描述】:

我试图将 char 数组从 java 传递给 c。我已经用谷歌搜索了实现它的方法。但是当我尝试访问数组的值时,值不正确。

事实上,我试图给数组一个字符。就像buffer[i]='z',结果在android中是正确的。

顺便说一句,我想要的值是 rs232 发送的值。 rs232 的值没问题。

有人告诉我使用字节数组。它会起作用吗?我担心来自 rs232 的值无法存储到 bytearray 中......

Java

public native int OpenPort(int portnum,int brates);
public native int ClosePort(int portnum);
public native int READ(char[] databuffer);

public char[] buffer=new char[40];

int i;

for(i=0;i<40;i++)
    buffer[i]='s';  //initialization

OpenPort(16,9600); // A function to open the rs232 port

while (i<1000)
{
    READ(buffer);
    i++;
}

JNI.c

JNIEXPORT jint JNICALL Java_com_example_ndk_Vehicles_READ(JNIEnv *env, jclass
cls,jcharArray databuffer)
{

    char tmp[40];
    jchar *buffer=(*env)->GetCharArrayElements(env,databuffer,0);
    memset(tmp,0,sizeof(tmp));
    PollComport(16,tmp,40); //will the problem here ? This function need a unsigned char[]
                            //,but in the c program I wrote , char[] was ok for this.
    memcpy(buffer,tmp,40);

    (*env)->ReleaseCharArrayElements(env, databuffer, buffer, 0);

    return 0;
}

【问题讨论】:

  • 如果你想将 char 数组从 java 传递给 c,我建议你将它们作为 char* 传递
  • 如果你想使用字节数组然后使用这个 jbyteArray jb; jb=(*env)->NewByteArray(env, finfo.st_size); (*env)->SetByteArrayRegion(env, jb, 0, finfo.st_size, (jbyte *)m); close(fd); 数组可以通过 (*env)-> ReleaseByteArrayElements(env, jb, (jbyte *)m, 0); 显式释放
  • 对象数组和基元类型数组的区别在于构造jobjectarray类型时,使用Java语言类作为参数。
  • 如何将 char[] 从 Java 发送到此 JNI 调用? String.getBytes() ?还是 String.getBytes("UTF-8") ?
  • 您将 16 位的 Java char 与 8 位的 C char 混淆了。您需要在此处始终使用 Java byte,包括您的 Java 端代码。

标签: java android java-native-interface


【解决方案1】:

因为允许 GetCharArrayElements() 制作 Java 数组的副本并将指向该副本的指针交给您。在您的代码中,您为指向布尔参数的指针传递了 null,该参数会告诉您是否制作了副本:

jchar *buffer=(*env)->GetCharArrayElements(env,databuffer,0);

因此,您可能正在对完成后丢弃的副本进行操作。代替 GetCharArrayElements(),在 C++ 中对本地数组进行操作并使用 SetCharArrayRegion() 来复制它们。

【讨论】:

    【解决方案2】:

    这是一个简单的例子

    public native int play(String filename_main, String filename_prev, int main_x, int main_y, int main_width, int main_height, int preview_x, int preview_y, int preview_width, int preview_height);
    

    映射到

    int play(char* filename_main, char* filename_preview, int main_x, int main_y, int main_width, int main_height, int preview_x, int preview_y, int preview_width, int preview_height)
    

    使用这个 JNI 调用。

    JNIEXPORT jint JNICALL Java_com_rtrk_demo_PELib_play(JNIEnv *env, jobject obj, jstring main_video, jstring prev_video, jint main_x, jint main_y, jint main_width, jint main_height, jint prev_x, jint prev_y, jint prev_width, jint prev_height)
    {
    LOGI("JNICALL - Java_com_rtrk_demo_PELib_play(filename)\n");
    
    const char* utf_main_video = env->GetStringUTFChars(main_video, 0);
    const char* utf_prev_video = env->GetStringUTFChars(prev_video, 0);
    char* file_main_video = (char*) malloc(strlen(utf_main_video) * sizeof(char) +1);
    char* file_prev_video = (char*) malloc(strlen(utf_prev_video) * sizeof(char) +1);
    strcpy(file_main_video, utf_main_video);
    strcpy(file_prev_video, utf_prev_video);
    LOGI("JNICALL - filenames: %s\t%s\n", file_main_video, file_prev_video);
    env->ReleaseStringUTFChars(main_video, utf_main_video);
    env->ReleaseStringUTFChars(prev_video, utf_prev_video);
    LOGI("###JNICALL RET - Java_com_rtrk_demo_PELib_play(%s, %s)\n", file_main_video, file_prev_video);
    
    int retVal = play(file_main_video, file_prev_video, (int)main_x, (int)main_y, (int)main_width, (int)main_height, (int)prev_x, (int)prev_y, (int)prev_width, (int)prev_height);
    free(file_main_video);
    free(file_prev_video);
    return retVal;
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-03
      • 2016-10-24
      • 1970-01-01
      • 1970-01-01
      • 2020-06-15
      • 1970-01-01
      • 1970-01-01
      • 2015-02-17
      • 1970-01-01
      相关资源
      最近更新 更多