JNI:从C代码到Java和JNI

时间:2011-06-02 13:45:11

标签: java android c eclipse java-native-interface

背景

我正在开发eclipse中的android应用程序,现在我遇到了问题,我需要你的帮助。所以我必须从JAVA应用程序中调用 C 中编写的函数。但在我编写代码的过程中,我有一些 问题 ,您可以在下面看到。我在等你的答案和想法......

C代码:

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代码:

在JAVA代码而不是unsigned long我使用int所以我可以写。

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.* );

}

问题1。

  • 在JAVA代码中我可以使用什么代替unsigned char
  • 我必须用JAVA代码而不是unsigned char data[1];编写什么?

问题2。

  • 如何在JAVA代码中使用class jblobData_c代替blobData_t* pInputInfo
  • 我必须用JAVA而不是blobData_t* pInputInfo写什么?

JNI代码:

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.*);
}

问题3。

  • 我必须在CheckEnrollmentExist函数中编写C代码函数而不是blobData_t* pInputInfo,以使此函数正常工作且给定参数相同

参考

  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

1 个答案:

答案 0 :(得分:2)

问题#1:

您可以使用jchar。 java中的原始字符没有签名,它是唯一没有的原语。请注意,jchar是一个UTF-16字符,因此您必须将jchar“映射”到常规字符,就像任何字符转换问题一样。对于简单的转换,通常可以通过强制转换来完成

char c_char = (char)java_char;

因为核心ASCII在ASCII和UTF-16之间共享相同的数值。但是,如果任何人实际尝试通过接口传递“特殊”字符,则容易出错。一个更好的方法是(在java方面,因为它更容易)使用适合您的平台的字符集将字符转换为字节(以确保C层中的平台兼容性)。然后你只需要将一个byte []传递给JNI调用,这些字节将正确地对应于C可能期望的字符。

对于问题#2:

如果CheckEnrollmentExists(...)方法是JNI绑定入口点,则无法安全地更改数据类型。这意味着所有输入输入必须是JNI数据类型值。虽然您可能能够选择C数据类型等价物(并且您可能能够让编译器完成它),但这种技术应该不受欢迎。这隐含意味着JNI入口点不能接受未在JNI头中定义的结构数据结构。换句话说,您无法将自己的结构传递给方法。

如果方法需要跨调用访问C结构,请使用其他方法。我已经看到人们将指针存储在成员整数或长整数(正确的转换)中的已分配数据结构中。然后,您可以重写本机代码端以从传入调用的“this”对象中检索指针,并执行取消引用以获取所需数据。

对于问题#3:

这实际上与问题#2相同。在您放置的“绑定包装器”中,您将在java对象的int或long字段中检索指针的存储值,将其强制转换为相应的结构指针,然后将其传递给内部方法。由于指针的传递是C到C调用,因此不需要额外的魔法。