Это был просто пост, но место ему тут 
итак:
класс для теста
Java | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| import java.io.File;
import java.util.Vector;
public class Runner {
public static void main(String[] args) {
String[] sa = {"a", "b", "c"};
File f = new File("");
// чтобы не кидать либку в системную директорию - грузим её по абсолютному пути явным образом
// так как я из нетбинса пускал то у меня вот так складывается путь
System.load(f.getAbsolutePath() + "/src/libJNIInvoker.so");
Vector<MyClass> v = JNIInvoker.nativeGetMy(sa);
for (MyClass mc : v) {
System.out.println(mc.toString());
}
}
} |
|
класс с нативом
Java | 1
2
3
4
5
| import java.util.Vector;
public class JNIInvoker {
public static native Vector<MyClass> nativeGetMy(String[] s);
} |
|
кастом класс
Java | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| public class MyClass {
private String s;
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
@Override
public String toString() {
return "MyClass [s=" + s + "]";
}
} |
|
компилимся
генерим хедер
получаем хедер JNIInvoker.h
C++ (Qt) | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| /* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNIInvoker */
#ifndef _Included_JNIInvoker
#define _Included_JNIInvoker
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JNIInvoker
* Method: nativeGetMy
* Signature: ([Ljava/lang/String;)Ljava/util/Vector;
*/
JNIEXPORT jobject JNICALL Java_JNIInvoker_nativeGetMy
(JNIEnv *, jclass, jobjectArray);
#ifdef __cplusplus
}
#endif
#endif |
|
имплементим хедер JNIInvoker.cpp
C++ (Qt) | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| #include <jni.h>
#include "JNIInvoker.h"
/*
* Class: JNIInvoker
* Method: nativeGetMy
* Signature: ([Ljava/lang/String;)Ljava/util/Vector;
*/
JNIEXPORT jobject JNICALL Java_JNIInvoker_nativeGetMy
(JNIEnv *env, jclass jc, jobjectArray ja) {
// C стиль вызовов
jsize stringCount = (*env).GetArrayLength(ja);
jclass retclazz = (*env).FindClass("java/util/Vector");
jobject ret = (*env).NewObject(retclazz, (*env).GetMethodID(retclazz, "<init>", "()V"));
// C++ стиль вызовов
jclass myclazz = env->FindClass("MyClass");
for (int i = 0; i < stringCount; i++) {
jstring str = (jstring) env->GetObjectArrayElement(ja, i);
jobject myobj = env->NewObject(myclazz, env->GetMethodID(myclazz, "<init>", "()V"));
jmethodID setS = env->GetMethodID(myclazz, "setS", "(Ljava/lang/String;)V");
env->CallVoidMethod(myobj, setS, str);
jmethodID add = env->GetMethodID(retclazz, "add", "(Ljava/lang/Object;)Z");
env->CallVoidMethod(ret, add, myobj);
}
return ret;
} |
|
компилимся в либку
Bash | 1
| g++ -x c++ -shared -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux -o libJNIInvoker.so JNIInvoker.cpp |
|
всё можно запускать
Bash | 1
2
3
4
5
| run:
MyClass [s=a]
MyClass [s=b]
MyClass [s=c]
BUILD SUCCESSFUL (total time: 0 seconds) |
|
|