Я писал программу, которая должна использовать JNI, которая имеет следующие шаги:
Создать объект на стороне C ++
Позвоните в Java, чтобы сделать что-то
вернуть объект, созданный в 1
ниже приведен код, который долго передает Java:
MyClass.java
public class MyClass{
static{
System.loadLibrary("MyClass");
}
public static native void init();
public static native void testCpp(long buf);
public static void testJava(long buf){
testCpp(buf);
}
public static void main(String[] args){
init();
}
}
MyClass.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyClass */
#ifndef _Included_MyClass
#define _Included_MyClass
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: MyClass
* Method: init
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_MyClass_init
(JNIEnv *, jclass);
/*
* Class: MyClass
* Method: testCpp
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_MyClass_testCpp
(JNIEnv *, jclass, jlong);
#ifdef __cplusplus
}
#endif
class MyClass{
public:
int myInt;
};
#endif
MyClass.cpp
#include "MyClass.h"JNIEXPORT void JNICALL Java_MyClass_init(JNIEnv *env, jclass clazz){
MyClass* myClass=new MyClass();
myClass->myInt=123;
long myClass_pointer=(long)myClass;
env->CallStaticVoidMethod(env->FindClass("MyClass"),env->GetStaticMethodID(env->FindClass("MyClass"),"testJava","(J)V"),myClass_pointer);
}
JNIEXPORT void JNICALL Java_MyClass_testCpp(JNIEnv * env,jclass clazz, jlong addr){
MyClass* myClass=reinterpret_cast<MyClass*>(addr);
printf("%d\n",myClass->myInt);
delete myClass;
}
но я также нахожу некоторые сообщения, что он может сначала преобразовать указатель объекта в ByteBuffer, а затем перейти на сторону Java:
MyClass.java
import java.nio.ByteBuffer;
public class MyClass{
static{
System.loadLibrary("MyClass");
}
public static native void init();
public static native void testCpp(ByteBuffer buf);
public static void testJava(ByteBuffer buf){
testCpp(buf);
}
public static void main(String[] args){
init();
}
}
MyClass.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyClass */
#ifndef _Included_MyClass
#define _Included_MyClass
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: MyClass
* Method: init
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_MyClass_init
(JNIEnv *, jclass);
/*
* Class: MyClass
* Method: testCpp
* Signature: (Ljava/nio/ByteBuffer;)V
*/
JNIEXPORT void JNICALL Java_MyClass_testCpp
(JNIEnv *, jclass, jobject);
#ifdef __cplusplus
}
#endif
class MyClass{
public:
int myInt;
};
#endif
MyClass.cpp
#include "MyClass.h"JNIEXPORT void JNICALL Java_MyClass_init(JNIEnv *env, jclass clazz){
MyClass* myClass;
myClass->myInt=12345;
jobject myClass_pointer=env->NewDirectByteBuffer(myClass,sizeof(myClass));
env->CallStaticVoidMethod(env->FindClass("MyClass"),env->GetStaticMethodID(env->FindClass("MyClass"),"testJava","(Ljava/nio/ByteBuffer;)V"),myClass_pointer);
}
JNIEXPORT void JNICALL Java_MyClass_testCpp(JNIEnv * env,jclass clazz, jobject obj){
MyClass* myClass=(MyClass*)env->GetDirectBufferAddress(obj);
printf("%d\n",myClass->myInt);
delete myClass;
}
Я просматриваю некоторые посты о том, как передать указатель c ++ на сторону Java, кажется, что многие из них предлагали решения о long или ByteBuffer или только один, но редкие из них сравнивают между long и ByteBuffer. Также я обнаружил, что некоторые владельцы вопросов используют долго, а иногда используют ByteBuffer.
Какой из них лучше базируется на безопасных типах и кроссплатформенных долго? ByteBuffer? или другой тип данных? или в другом вопросе: когда использовать long и когда использовать ByteBuffer?
Задача ещё не решена.