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使用碰到的问题的主要内容,如果未能解决你的问题,请参考以下文章