我有一个已编译的库,需要在项目中使用。简而言之,它是一个用于与特定硬件交互的库。我拥有的是 .a 和 .dll 库文件,分别适用于 Linux 和 Windows,以及一堆 C++ .h 头文件,其中包含其中描述的所有公共函数和类。
问题是该项目需要使用 Java,因此我需要为这个库编写一个 JNI 包装器,老实说,我从未这样做过。不过没关系,我正准备学习这个东西。
我在线阅读了一堆文档,并且弄清楚了传递变量、从本机代码创建 java 对象等。
我不明白的是如何使用 JNI 来处理本机构造函数?我不知道这些构造函数的源代码是什么,我只有这样的标题:
namespace RFDevice {
class RFDEVICE_API RFEthernetDetector
{
public:
//-----------------------------------------------------------------------------
// FUNCTION RFEthernetDetector::RFEthernetDetector
/// \brief Default constructor of RFEthernetDetector object.
///
/// \return void : N/A
//-----------------------------------------------------------------------------
RFEthernetDetector();
RFEthernetDetector(const WORD wCustomPortNumber);
所以基本上如果我用 C++ 编写程序(我不能),我会做类似的事情
RFEthernetDetector ethernetDetector = new RFEthernerDetector(somePort);
然后处理该对象。但是...我如何使用 JNI 在 Java 中执行此操作?
我不明白我应该如何为构造函数创建一个本机方法,该方法将从我的 .a 库调用构造函数,然后以某种方式处理该特定对象?我知道如何从本机代码创建 java 对象 - 但问题是我没有任何有关 RFEthernetDetector 类的内部结构的信息 - 只有其中的一些公共字段和公共方法。
我似乎无法在网上找到合适的文章来帮助我。我怎么做?
更新:进一步澄清一下。
我创建一个 .java 包装类,如下所示:
public class RFEthernetDetector
{
public RFEthernetDetector(int portNumber)
{
Init(portNumber);
}
public native void Init(int portNumber); // Void? Or what?
}
然后我用 -h 参数编译它以生成 JNI .h 文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class RFEthernetDetector */
#ifndef _Included_RFEthernetDetector
#define _Included_RFEthernetDetector
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: RFEthernetDetector
* Method: Init
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_RFEthernetDetector_Init
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
然后,我创建一个实现,它将调用我的 .a 库中的函数:
#include "RFEthernetDetector.h" // auto-generated JNI header
#include "RFEthernetDetector_native.h" // h file that comes with the library,
//contains definition of RFEthernetDetector class
/*
* Class: RFEthernetDetector
* Method: Init
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_RFEthernetDetector_Init(JNIEnv *env, jobject thisObj, jint value)
{
RFEthernetDetector *rfeDetector = new RFEthernetDetector(value); // constructor from the library
// now how do I access this new object from Java?
// if I need to later call rfDetector->doSomething() on that exact class instance?
}