【问题标题】:JNI: From C code to Java and JNIJNI:从 C 代码到 Java 和 JNI
【发布时间】:2011-09-07 02:33:35
【问题描述】:

背景

我正在 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,一个字节就是你想要的。也遇到了另一个帖子stackoverflow.com/questions/3923299/…
  • "一个字节就是你想要的。"你可以解释吗 ?谢谢!
  • 抱歉,查看 Java 规范确实有一个字节是有符号的......

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


【解决方案1】:

对于问题 #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 的调用,因此不需要额外的魔法。

【讨论】:

  • 对不起,您的回答对我没有帮助,因为它不包含任何有用的链接或如何解决我的问题的示例。您能否给我更多详细信息或文章或一些链接,以便我可以查看它们并找到我的问题的答案!非常感谢!
  • @ViTo,有什么问题?你问了三个具体问题。传递给 JNI 绑定方法的所有参数都必须是 jni.h 声明的数据类型。在 C 中,您需要根据需要进行转换。如果进行分配,则需要将每个对象的指针存储在 Java 类中,以便当该类返回 JNI 层时,您可以访问指针。
猜你喜欢
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 2019-10-06
相关资源
最近更新 更多