JNI:从C code到Java和JNI [英] JNI: From C code to Java and JNI

查看:169
本文介绍了JNI:从C code到Java和JNI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

我开发的机器人在Eclipse的应用程序,现在我有一个问题,我需要你的帮助。所以我必须调用函数编写的 C 从Java应用程序。但在我的写作code的方式,我有一些的问题,你可以看到下面。我在等待你的答案和想法......

C code:

  typdef结构blobData_s {
    无符号长的长度;
    unsigned char型数据[1];
} blobData_t;

无符号整数CheckEnrollmentExist(无符号长hdevice,blobData_t * pInputInfo){
    //函数code到这里
    ..........................
    返回some_value;
}
 


JAVA code:

在JAVA code,而不是无符号长我用 INT 这样我就可以写了。

 类jblobData_c {
    公众诠释langth;
    *问题1。*
}

公共类ApplicationMainClass延伸活动{
    //有些code到这里
    ......................

    公共本地INT JCheckEnrollmentExist(INT jhdevive,*问题2. *);

}
 

问题1

  • 我可以使用无符号的字符的是什么,而不是在JAVA code?
  • 我必须JAVA code,而不是 unsigned char型数据[1]写;

问2。

  • 如何使用类jblobData_c 而不是 blobData_t * pInputInfo 在JAVA code?
  • 我必须写,而不是在JAVA blobData_t * pInputInfo

JNI code:

  JNIEXPORT jint JNICALL Java_com_Test_JCheckEnrollmentExist(JNIEnv的* ENV,jobject OBJ,jint jhdevice,*问题2. *){

    //调用从C code中的基础作用。
    返回CheckEnrollmentExist(jhdevice,*问题3. *);
}
 

问题3。

  • 我必须在 CheckEnrollmentExist 编写函数是 blobData_t * pInputInfo 在C code函数,而不是订购此功能工作的权利,并给定参数相同

参考

  1. <一个href="http://stackoverflow.com/questions/3923299/how-to-pass-c-structs-back-and-forth-to-java-$c$c-in-jni">How通过C结构来回的Java code在JNI?
  2. <一个href="http://stackoverflow.com/questions/1571175/passing-large-c-structure-through-jni-efficiently">Passing通过JNI大型C结构,有效地
  3. <一个href="http://www.$c$cranch.com/t/274504/java/java/Return-Structure-Object-Java-Through">Return一个结构的对象从C到Java通过JNI
  4. <一个href="http://stackoverflow.com/questions/4324819/pass-data-between-java-and-c/4325678#4325678">Pass Java和C之间的数据
  5. <一个href="http://stackoverflow.com/questions/5802340/passing-a-pointer-from-jni-to-java-using-a-long">Passing从JNI使用长
  6. 指针的Java
  7. <一个href="http://stackoverflow.com/questions/1632367/passing-pointers-between-c-and-java-through-jni">Passing通过JNI
  8. C和Java之间的指针
解决方案

有关问题#1:

您可以使用jchar。在Java原始字符没有签名,这是他们唯一原语并非如此。需要注意的是jchar是UTF-16字符,所以你必须要地图jchar到普通字符,因为你将不得不使用任何字符转换的问题。对于简单的转换,这通常可以通过浇铸完成

 字符c_char =(焦炭)java_char;
 

因为核心的ASCII股的ASCII和UTF-16之间是相同的数值。然而,这是容易出错应该任何人实际上试图通过接口传递一个特殊的性格。更好的方法是将(在Java方面,因为它是更容易)转换成字符用适当的字符集为您的平台字节(以确保在C层平台的兼容性)。然后,你只需要一个byte []传递给JNI调用,并且字节将正确地对应于ç可能会期望的字符。

有关问题#2:

如果你的 CheckEnrollmentExists(...)方法是JNI绑定入口点,你不能改变数据类型安全。这意味着,所有入口输入必须JNI数据类型值。虽然你也许可以选​​择C数据类型当量(您可能能够得到你的编译器也会这么做吧)这样的技术应该会让人不悦。这隐含地意味着JNI入口点不能接受的JNI头文件没有定义的结构数据结构。换句话说,你无法通过你自己的结构的方法。

如果该方法需要访问在调用C结构,用另一种方式。我见过人们的指针分配的数据结构存储在一个成员的整数或长(做正确的铸造)。然后,您可以重写本地code面,从此对象检索指针被传递到电话,以及做一个解引用,以获取所需的数据。

有关问题3:

这其实是一样的问题,#2。在绑定包装你说,你会找回在Java对象的int或长字段的指针中存储的值,将其转换为相应的结构指针,然后将它传递给内部方法。随着指针的传递是C到C调用,没有多余的魔术是必需的。

Background

I am developing an application for android in eclipse and now I have a problem and I need your help. So I must Call function written in C from JAVA application. But on my way of writing code I have some Questions which you can see below. I am waiting for your answers and ideas ...

C Code:

typdef struct blobData_s {
    unsigned long length;
    unsigned char data[1];
} blobData_t;

unsigned int CheckEnrollmentExist ( unsigned long hdevice, blobData_t* pInputInfo ) {
    // Function code goes here
    ..........................
    return some_value;
}


JAVA Code:

In JAVA code instead of unsigned long I use int so I can write.

class jblobData_c {
    public int langth;
    *Question 1.*
}

public class ApplicationMainClass extends Activity {
    // Some code goes here
    ......................

    public native int JCheckEnrollmentExist( int jhdevive, *Question 2.* );

}

Question 1.

  • What I can use instead of unsigned char in JAVA Code ?
  • What I must write in JAVA code instead of unsigned char data[1]; ?

Question 2.

  • How I can use class jblobData_c instead of blobData_t* pInputInfo in the JAVA Code ?
  • What I must write in JAVA instead of blobData_t* pInputInfo ?

JNI Code:

JNIEXPORT jint JNICALL Java_com_Test_JCheckEnrollmentExist(JNIEnv* env, jobject obj, jint jhdevice, *Question 2.* ) {

    // Call the base function from C code.
    return CheckEnrollmentExist( jhdevice, *Question 3.*);
}

Question 3.

  • What I must write in CheckEnrollmentExist function that is C Code Function instead of blobData_t* pInputInfo in order this function works right and given parameter be the same

Reference

  1. How to pass C structs back and forth to Java code in JNI ?
  2. Passing large C structure through JNI efficiently
  3. Return a Structure Object from C to Java Through JNI
  4. Pass data between Java and C
  5. Passing a pointer from JNI to Java using a long
  6. Passing pointers between C and Java through JNI

解决方案

For question #1:

You can use a jchar. Primitive chars in java are not signed, it's about the only primitive that isn't. Note that jchar is a UTF-16 char, so you will have to "map" the jchar to a regular char, as you would have to with any character conversion issue. For simple conversions, this can typically be done by casting

char c_char = (char)java_char;

because the core ASCII shares the same numeric values between ASCII and UTF-16. However, this is prone to error should anyone actually attempt to pass a "special" character through the interface. A much better way would be to (in the java side, as it is easier) convert the characters to bytes using the appropriate character set for your platform (to ensure platform compatibility in the C layers). Then you only need to pass a byte[] to the JNI call, and the bytes will correctly correspond to the characters that C likely will expect.

For question #2:

If your CheckEnrollmentExists(...) method is the JNI binding entry point, you cannot change data types safely. That means that all entry inputs must be JNI data type values. While you might be able to select the C data type equivalents (and you might be able to get your compiler to do it anyway) such techniques should be frowned upon. This implicitly means that JNI entry points cannot accept struct data structure not defined in the JNI headers. In other words, you can't pass your own struct to the method.

If the method needs access to a C struct across calls, use another means. I've seen people store the pointer to the allocated data structure in a member integer or long (doing correct casting). You can then rewrite the native code side to retrieve the pointer from the "this" object being passed into the call, and the do a dereference to obtain the required data.

For Question #3:

This is actually the same as question #2. In the "binding wrapper" you put, you would retrieve the pointer's stored value in the java object's int or long field, cast it to the appropriate struct pointer and then pass it to the internal method. As the passing of the pointer is a C to C call, no extra magic is required.

这篇关于JNI:从C code到Java和JNI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆