JNI Java 使用将对象作为参数的 DLL 函数
JNI Java using DLL function which takes an object as param
我将需要使用外部的未知 DLL 并围绕它构建一个 java 包装器。我现在没有 DLL 也没有头文件,也许连头文件都拿不到,但我想自己做好准备。 (我没有使用 C++ 的经验)
以下情况:
假设这个 DLL 有一个函数,它包含一个或多个 C++ classes 作为方法签名。那么我怎么能用 JNI 调用这个函数,因为在我的 java 项目中,DLL 中的那些自定义 classes 是不存在的?是否有 "clone" 或 "port" C++ class 到 java 的选项?我可以使用像 Dependency Walker 这样的工具来解决这个问题吗?
实现该目标的最佳/最简单方法是什么?
这是我已经尝试过的一些代码,以了解它的行为方式:
Java Class 与 main
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
此处最好的方法是使用适配器模式 (https://en.wikipedia.org/wiki/Adapter_pattern)。在您的 JNI
代码中,您必须通过创建所有对象来调用 DLL
,正如 C++
API 所期望的那样。
您可以在此处找到样本:http://jnicookbook.owsiak.org/recipe-No-021/ and here https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo025
您还可以查看一个共享库 (JNI
) 调用另一个共享库的代码:http://jnicookbook.owsiak.org/recipe-No-023/
基本上,您要做的是创建基于 JNI
的包装器代码,将对本机方法的 Java
调用转换为 C++
调用,反之亦然 - 转换的代码return 值转换为 Java 所期望的值。
我将需要使用外部的未知 DLL 并围绕它构建一个 java 包装器。我现在没有 DLL 也没有头文件,也许连头文件都拿不到,但我想自己做好准备。 (我没有使用 C++ 的经验)
以下情况:
假设这个 DLL 有一个函数,它包含一个或多个 C++ classes 作为方法签名。那么我怎么能用 JNI 调用这个函数,因为在我的 java 项目中,DLL 中的那些自定义 classes 是不存在的?是否有 "clone" 或 "port" C++ class 到 java 的选项?我可以使用像 Dependency Walker 这样的工具来解决这个问题吗?
实现该目标的最佳/最简单方法是什么?
这是我已经尝试过的一些代码,以了解它的行为方式:
Java Class 与 main
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
此处最好的方法是使用适配器模式 (https://en.wikipedia.org/wiki/Adapter_pattern)。在您的 JNI
代码中,您必须通过创建所有对象来调用 DLL
,正如 C++
API 所期望的那样。
您可以在此处找到样本:http://jnicookbook.owsiak.org/recipe-No-021/ and here https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo025
您还可以查看一个共享库 (JNI
) 调用另一个共享库的代码:http://jnicookbook.owsiak.org/recipe-No-023/
基本上,您要做的是创建基于 JNI
的包装器代码,将对本机方法的 Java
调用转换为 C++
调用,反之亦然 - 转换的代码return 值转换为 Java 所期望的值。