JNI使用碰到的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JNI使用碰到的问题相关的知识,希望对你有一定的参考价值。

参考技术A 记录下使用JNI的诡异问题

1.传递String或int出错

正常:static int _open(JNIEnv *env, jclass thisz,  jstring path, int speed)

出问题:static int _open(JNIEnv *env, jstring path, int speed)

出错的原因是 : 把 jclass thisz 去掉了

2. jniRegisterNativeMethods 出错,提示找不到对应java方法

原因:java文件里的native方法未被使用,编译的时候会被优化,这样导致jni找不到注册失败

使用 C++ (JNI) 包装 Java 库

【中文标题】使用 C++ (JNI) 包装 Java 库【英文标题】:Wrapping a Java library with C++ (JNI) 【发布时间】:2018-10-14 21:39:20 【问题描述】:

我有一个用 C++ 编写的大型程序,需要使用特定的 Java 库。理想情况下,我想创建一个等效的 C++ 库来包装这个现有的 Java 代码。因此,我一直在研究 JNI 调用 API。

由于我不是一个非常有经验的程序员,而且我对 JNI 和多语言编程也缺乏经验,我非常感谢一些关于如何解决这个问题的一般性指针/提示/建议。

我特别想知道的事情:

    Java 库中的每个 Java 类是否应映射到关联的 C++ 班级? IE。在我的 C++ 库中,我会有一个类,每个类都调用一个 特定Java类的JVM?或者我会有一个单一的 JVM,通过它可以访问所有内容?最好的方法是什么?为什么? 执行此操作的基本流程和架构是什么? 是否有任何特定资源可用于使用调用 API 从 Java 库创建 C++ 库?

非常感谢!

【问题讨论】:

【参考方案1】:

我以前做过这个,但它不适合胆小的人,尤其是当你在两种语言之间的界面很难时。在这种情况下,调试也很痛苦。

回答你的观点:

    您应该首先决定您需要在 C++ 程序中访问 Java 库中的哪些功能。只是几个任务吗?在这种情况下,尝试制作一个从 C++ 到 Java 的非常简单的接口。复杂吗?然后你必须开始将 Java 类映射到 C++,你需要的越多,工作就越多。

    q1 的结尾确实有点像 q2。您的 C++ 程序将启动一个 JVM,该 JVM 将作为程序的一部分运行。当您跨 C++ 进行调用时,数据将被传输到 JVM,然后执行 Java 代码,然后将返回值传回。这会产生性能成本,因此通过 JNI 调用像 add(int,int) 这样的小函数将比仅在 C++ 中调用更昂贵。

    您可以通过 Google 搜索很多基本指南来开始使用。仅仅设法从 C++ 启动一个基本的 JVM 并进行调用实际上是一项工作,因为您需要正确获取 JVM 库的路径,否则它不起作用(除非他们已经改进了这一点,自从我试过)。因此,在询问有关 JNI 和映射函数的更具体问题之前,您可能需要先检查一下。

另一种选择(根据您的库和用例可能会也可能不会)是只在您的库周围编写某种包装服务,实际上是在 Java 中。然后通过 JSON-HTTP 或一些消息系统向它发送请求。

还有一个更好的选择,用 C++ 重写库所做的任何事情。

【讨论】:

太好了,谢谢。就我而言,我只对运行 Java 库中的一些方法感兴趣,但是,这些方法需要从库中的许多不同类中创建许多对象。我已经玩过 JNI 并且遇到了同样的问题!尽管最终我确实设法启动并运行了 JVM :) 感谢您的建议 - 值得考虑!【参考方案2】:

您可以使用scapix::link::java C++ JNI 库为任何 Java 代码生成 C++ 标头,然后从 C++ 轻松访问此 Java 代码。这是example:

#include <scapix/java_api/java/lang/System.h>
#include <scapix/java_api/java/util/Locale.h>
#include <scapix/java_api/java/text/DateFormatSymbols.h>

using namespace scapix::link::java;
using namespace scapix::java_api;

void test1()

    // C++ objects are automatically converted to and from corresponding Java types.
    // This works for any type supported by scapix::link::java::convert() interface,
    // which supports many STL types and can be extended for your own types.

    std::string version = java::lang::System::getProperty("java.version");
    std::vector<std::string> languages = java::util::Locale::getISOLanguages();
    std::vector<std::vector<std::string>> zone_strings = java::text::DateFormatSymbols::getInstance()->getZoneStrings();
    std::map<std::string, std::string> properties = java::lang::System::getProperties();

【讨论】:

以上是关于JNI使用碰到的问题的主要内容,如果未能解决你的问题,请参考以下文章

Android通过JNI实现与C语言的串口通讯操作蓝牙硬件模块

初学boost碰到点问题

一点碰到的基础

Linux系统使用NAT模式连通主机碰到过的问题和解决方法

使用easyPOI时碰到的几个问题(记录一下)

集成融云即时通讯碰到的一些问题