vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_FALSE;
jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
delete options;
if (rc != JNI_OK) {
cin.get();
exit(EXIT_FAILURE);
}
cout << "JVM load succeeded: Version ";
jint ver = env->GetVersion();
cout << (((int) ver >> 16) & 0x0f) << "." << ((int)ver & 0x0f) << endl;
jclass thisClass = env->FindClass("Test");
cout << thisClass << endl;
jmethodID constructor = env->GetMethodID(thisClass, "<init>", "()V");
cout << constructor << endl;
jobject testObject = env->NewObject(thisClass, constructor);
jmethodID getExpression = env->GetMethodID(thisClass, "getExpression", "()Lscala/collection/mutable/ArrayOps;");
我正在尝试使用JNI从C ++调用Scala函数,将Scala对象返回到C ++,然后(手动)将返回的对象转换为可以传递给本机方法的C ++对象。
我知道从C ++通过JNI访问Scala时会有一些小问题,但我很欣赏一些关于如何执行此操作的指示。
非常感谢。
答案 0 :(得分:1)
一般建议是在尝试处理scala类之前检查生成的字节代码。有时scalac
可能会产生非直观繁琐的字节码。例如案例类
case class CaseClass(value: Int)
将被编译为类似的东西(输出由procyon
生成)
public class CaseClass {
public static CaseClass apply(int p0) {
return:CaseClass(invokevirtual:CaseClass(CaseClass$::apply, getstatic:CaseClass$(CaseClass$::MODULE$), p0:int))
}
public int value() {
return:int(getfield:int(CaseClass::value, this:CaseClass))
}
// the rest is omitted
}
在这种情况下,为了获得CaseClass
value
,您必须
jmethodID apply = env->GetStaticMethodID(thisClass, "apply", "(I)LCaseClass;");
jobject object = env->CallStaticObjectMethod(thisClass, apply, 5);
jmethodID getValue = env->GetMethodID(thisClass, "value", "()I");
jint value = env->CallIntMethod(object, getValue);