【发布时间】:2019-12-21 02:09:16
【问题描述】:
我需要使用一个外部的、未知的 DLL 并围绕它构建一个 java 包装器。我现在没有 DLL 也没有头文件,可能连头文件都没有,但我想自己准备。 (我没有 C++ 经验)
以下情况:
假设这个 DLL 有一个函数,它包含一个或多个 C++ 类作为方法签名。那我怎么能用 JNI 调用这个函数,因为在我的 java 项目中,DLL 中的那些自定义类不存在?是否有将 C++ 类“克隆”或“移植”到 java 的选项?我可以使用 Dependency Walker 之类的工具来解决这个问题吗?
实现该目标的最佳/最简单方法是什么?
这是我已经尝试过的一些代码,以了解它的行为方式:
带有 main 的 Java 类
public class FourthJNI {
public static native int returnAgeOfHuman(int zuQuadrierendeZahl);
public static void main(String[] args) {
// /* This message will help you determine whether
// LD_LIBRARY_PATH is correctly set
// */
// System.out.println("library: "
// + System.getProperty("java.library.path"));
Human testHuman = new Human("abcde", 23, "M");
/* Call to shared library */
int ageOfHuman = FourthJNI.returnAgeOfHuman(5);
System.out.println(testHuman.toString());
System.out.println("Age: " + ageOfHuman);
}
}
生成 h 文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class FourthJNI */
#ifndef _Included_FourthJNI
#define _Included_FourthJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: FourthJNI
* Method: returnAgeOfHuman
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_FourthJNI_returnAgeOfHuman
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
【问题讨论】:
-
您最初是如何完成这项任务的?对于没有 C++ 经验的人来说,这不是一份工作。不,没有办法克隆/移植整个东西 - 即使 .H 文件可用。如果幸运的话,DepWalk 可以提供一些帮助(例如,界面不太繁琐),但这仍然是一项非常手动的工作。要回答您的问题,最好的方法是放弃这项任务。
-
我将添加到之前的评论中。除非您知道并且真正了解 C++,否则执行 JNI 工作对您来说不会太顺利。 JNI 本身就是脆弱的,需要有经验的人才能知道如何解决脆弱性。
-
这个“未知 DLL”的确切详细信息是什么?您需要了解详细信息,然后才能判断任务是否可以完成。因为您根本无法编写调用“未知”事物的代码。
-
@sstankov 这就是我的全部观点。你应该“包装”什么? “为此写一个包装器。”你:“它有什么作用?” “未知。”你甚至知道这个“未知的 DLL”是不是一个32- or 64-bit DLL?
-
还有另一种方法。找一个对 C++ 和 JNI(以及可能对已编译代码进行逆向工程)有丰富经验的人,然后付给他们一大笔钱。从财务上讲,这对管理层有多重要? OBTW,C++ 没有反射。
标签: java c++ c dll java-native-interface