我需要通过JNI从C ++调用一些Java方法。我的JNI实施基于
Is it possible to make a Java JNI which calls jdbc?
我的Java项目中有两个java文件。一种是定义一个类,另一种是包含c ++将调用的实际方法。
public class MyObject {
private static int no;
private static LocalDateTime time;
private static String status;
// getters, setters and toString
}
public class ObjectHandler {
public static MyObject objectReturnToC;
public static Object methodA (type1 arg1, type2 arg2, type3 arg3) {
objectReturnToC = new MyObject();
// setting fields in returnObject according to passed-in parameters
return objectReturnToC;
}
public static void methodB(Object objectReturnedFromC) {
// access fields in objectReturnedFromC, do computation and store in
}
}
我在Visual Studio 2010中创建了C ++ DLL。有JVM.cpp,JVM.h,JavaCalls.h和JavaCalls.cpp
#ifdef JAVACALLSDLL_EXPORTS
#define JAVACALLSDLL_API __declspec(dllexport)
#else
#define JAVACALLSDLL_API __declspec(dllimport)
#endif
namespace JavaCalls
{
class JavaCalls
{
public:
static JAVACALLSDLL_API void *javaMethodA(type1, type2, type3);
static JAVACALLSDLL_API string toString(void **javaObject);
static JAVACALLSDLL_API void javaMethodB(void **javaObject);
};
}
namespace JavaCalls
{
void *JavaCalls::javaMethodA(type1 arg1, type2 arg2, type3 arg3)
{
// invoke JVM
// Find class, methodID
jobject javaObject = CallStaticObjectMethod(jMain, "methodA",...);
return javaObject;
}
void JavaCalls::javaMethodB(void** javaObject) {
// invoke JVM
// Find class, methodID
CallStaticVoidMethod(jMain, "methodB",...);
}
}
C ++使用DLL调用Java methodA和methodB:
int main()
{
void* a = JavaCalls::JavaCalls::javaMethodA(arg1, arg2, arg3);
// doing other stuff and updating fields in a
JavaCalls::JavaCalls::javaMethodB(static_cast<void**>(a));
}
显然,传递指针,希望它可用于C ++是行不通的。但是我该怎么做才能将Java Object保存在C ++中并稍后将其传递给Java呢?我应该使用GetObjectField创建一个C ++结构并将Java Object字段映射到它吗?
答案 0 :(得分:3)
我不太明白你的代码中需要void**
的原因。如果要使界面不透明,只需使用void*
即可。另外,不要忘记在返回的NewGlobalRef()
上调用DeleteGlobalRef()
和jobject
- 这样可以防止垃圾收集器将其破坏:
void *JavaCalls::javaMethodA(type1 arg1, type2 arg2, type3 arg3)
{
jobject javaObject = CallStaticObjectMethod(jMain, "methodA",...);
return NewGlobalRef(jMain, javaObject);
}
void JavaCalls::javaMethodB(void* javaObject) {
CallStaticVoidMethod(jMain, "methodB", static_cast<jobject>(javaObject));
}
// add this method - it should be called when you finish using the object
void JavaCalls::ReleaseObject(void* javaObject) {
DeleteGlobalRef(jMain, static_cast<jobject>(javaObject));
}
答案 1 :(得分:0)
有一个名为javah.exe
的好助手程序。
编写您喜欢的代码,然后javah
执行.class
。它将为您创建一个完全兼容的.h
文件。
你将成为这个:
public class Test {
public class MyObject {
private int no;
private String status;
}
public class Callback {
public void callback(MyObject afterCpp) {
}
}
public native void register(Callback v, MyObject beforeCpp);
}
此标题:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Test */
#ifndef _Included_Test
#define _Included_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Test
* Method: register
* Signature: (LTest/Callback;LTest/MyObject;)V
*/
JNIEXPORT void JNICALL Java_Test_register
(JNIEnv *, jobject, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif
您只需将callback
调用到第3个c ++ - 参数。