JNI:从C代码到Java和JNI

Vik*_*yan 11 c java eclipse java-native-interface android

背景

我正在开发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;
}
Run Code Online (Sandbox Code Playgroud)

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

}
Run Code Online (Sandbox Code Playgroud)

问题1.

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

问题2.

  • 如何使用class jblobData_c而不是blobData_t* pInputInfo在JAVA代码中?
  • 我必须用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.*);
}
Run Code Online (Sandbox Code Playgroud)

问题3.

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

参考

  1. 如何在JNI中来回传递C结构到Java代码?
  2. 有效地通过JNI传递大型C结构
  3. 通过JNI将结构对象从C返回到Java
  4. 在Java和C之间传递数据
  5. 使用long将指针从JNI传递到Java
  6. 通过JNI传递C和Java之间的指针

Edw*_*uck 3

对于问题#1:

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

char c_char = (char)java_char;
Run Code Online (Sandbox Code Playgroud)

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

对于问题#2:

如果您的CheckEnrollmentExists(...)方法是 JNI 绑定入口点,则无法安全地更改数据类型。这意味着所有条目输入必须是 JNI 数据类型值。虽然您也许能够选择 C ​​数据类型的等效项(并且您也许能够让您的编译器执行此操作),但此类技术应该不受欢迎。这隐含地意味着 JNI 入口点不能接受未在 JNI 标头中定义的 struct 数据结构。换句话说,您无法将自己的结构传递给该方法。

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

对于问题#3:

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

  • @ViTo,什么问题?你问了三个具体问题。传递到 JNI 绑定方法的所有参数都必须是 jni.h 声明的数据类型。在 C 中,您需要进行适当的转换。如果进行分配,则需要将每个对象的指针存储在 Java 类中,以便当该类返回到 JNI 层时,您可以访问这些指针。 (2认同)