java - JNI : From C code to Java and JNI

标签 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 代码中,我使用 int 而不是 unsigned long,这样我就可以写了。

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:

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

char c_char = (char)java_char;

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

对于问题 #2:

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

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

对于问题 #3:

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

关于java - JNI : From C code to Java and JNI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6215374/

相关文章:

c - 将简单的 Windows ui 添加到控制台应用程序

java - 创建 uber-jar 遇到困难

java - 累积 getClickCount()

Java 更改托盘图标

java - Android Studio LibGDX 游戏不显示障碍物和地板

android - 支持所有 Android 平板分辨率

java - 同时执行多个Asynctask无法正常工作

Android TextView在不同屏幕尺寸下的大小

c - 接收到用户定义的信号时,进程不会取消暂停

c - union 内的数据结构(C 编程)