java – 使用JNI将Scala对象返回给C

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时会有一些小问题,但我很感激有关如何执行此操作的一些指示.

非常感谢.

最佳答案 一般的建议是在尝试处理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值,您必须这样做

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);
点赞