我可以在 Java 中控制 JNI 本机方法调用名称吗?

Posted

技术标签:

【中文标题】我可以在 Java 中控制 JNI 本机方法调用名称吗?【英文标题】:Can i control JNI native method invocation name in Java? 【发布时间】:2021-09-11 16:44:13 【问题描述】:

我遇到了一个问题。我使用 Chilkat for Java,据我所知,没有任何 Maven 回购。因为它是一个双组件库 - 我需要通过 System.load() 注入 .dll。这部分我很清楚,但它们也提供了一些东西,比如包装器,它调用 .dll 中的方法。

所以,我不想将他们的 .jar 导入到我的项目中,但是,然后我自己调用本机方法,它会因 java.lang.UnsatisfiedLinkError 而失败。因为,然后 java 尝试调用一个本地方法,它在它的名称的开头添加了一些东西。例如:如果我在我的包中声明了本地方法,那么它将被调用,java 会将所有包层次结构名称添加到它的名称中。

我可以通过它的名称直接调用本机方法,而不需要任何运行时“适应”吗?

【问题讨论】:

“这部分我很清楚”和UnsatisfiedLinkError 是两个完全矛盾的陈述。您已经购买了一些商业库,但您想要什么可能并不重要......当已经无法加载 DLL 时。 因为我理解,.dll 中的 if 方法称为 Java_com_chilcat_updateSomething。但是如果我要在我的包中声明一个本地方法,它在运行时的名称将是 Java_mypackage_UpdateSomething。相应地,JNI 也不会找到这个指针。我只能从他们的对象层次结构中调用他们的方法。但我想直接在我的应用程序中集成本机调用 如前所述,这是一些商业库,他们应该为他们的产品提供支持......这可能会在 Java 或本机汇编端使用加密和/或混淆。 一切都与 jni 的工作方式有关。有一个包含所有本机声明的类。即使我擦除库中的所有其他类(我可以这样做,因为它不是 Maven 依赖项。)它会起作用,并且我成功调用它们的方法,只是因为它放置在正确的包中,然后 jni 进行调用,它是添加正确的方法名,由包名组成。 问题是,我可以自动控制 jni 吗? 【参考方案1】:

javac 可以生成您可能正在寻找的绑定 ...DLL export viewer(以及其他几个)可以列出导出的方法。或者对于 SO,只需使用 dumpbin /EXPORTS ./filename。方法名称会在运行时更改是不现实的,这只会在构建时混淆它们时发生一次 - 这通常会排除所有需要保持可访问性(用于反射)的对象。

只需开始一个新的 JNI 项目,并了解它是如何工作的,并大大降低了复杂性。这个 JAR 仍有可能在本机程序集中传递许可信息,或者本机程序集为 JAR 执行加密功能。商业图书馆不应被视为开源 - 首先我会阅读他们的许可条款。

【讨论】:

以上是关于我可以在 Java 中控制 JNI 本机方法调用名称吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何跟踪从Java到C的JNI方法?

使用 JNI 在 Java 调用之间将本机对象保存在内存中

JNI- java.lang.UnsatisfiedLinkError:找不到本机方法

无法在 JNI 中更新作业

OSGI 无法在运行时通过 JNI 链接到本机方法

java中native方法的使用