如何在C代码中回调java方法(不是c中的jni方法)?

时间:2013-06-25 09:28:40

标签: java c callback java-native-interface

我在C方法中遇到如何回调 java方法的问题,这个c方法与JNI不同,生成c方法。不在参数列表中包含 JNIEnv JObject 参数。如何解决它或其他解决方法......

2 个答案:

答案 0 :(得分:1)

要从C程序执行Java方法,首先需要将JVM加载到C程序中。为此,您应该使用Invocation API,请参阅http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/invocation.html

答案 1 :(得分:0)

此方法将创建自己的JNI_CreateJavaVM方法并将其作为线程附加,然后在使用后立即将其释放。

加载计算机中安装的jvm.dll

TCHAR* dllpath = (char*)TEXT("C:\\Program Files\\Java\\jdk1.8.0_65\\jre\\bin\\server\\jvm.dll");
HMODULE jniModule = LoadLibrary(dllpath);

定义创建JVM的函数

typedef int (JNICALL * JNI_CreateJavaVM)(JavaVM** jvm, JNIEnv** env, JavaVMInitArgs* initargs);
JNI_CreateJavaVM createJavaVM = (JNI_CreateJavaVM)GetProcAddress(jniModule, "JNI_CreateJavaVM");

创建JVM

JavaVMOption* options = new JavaVMOption[1];
options[0].optionString = const_cast<char*>("-Djava.class.path=" USER_CLASSPATH);

JavaVMInitArgs initArgs;
initArgs.version = JNI_VERSION_1_6;
initArgs.nOptions = 1;
initArgs.options = options;
JavaVM* jvm;
JNIEnv* env;
DWORD retval;
if ((retval = createJavaVM(&jvm, &env, &initArgs)) != JNI_OK){
    cout << "beyond the scope of this answer" << endl;
    return 1;
}
jint retvalue = jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
bool mustDetach = false;

必要时分离JVM

if (retvalue == JNI_EDETACHED)
    {
        JavaVMAttachArgs args;
        args.version = JNI_VERSION_1_6;
        args.name = NULL;
        args.group = NULL;
        retvalue = jvm->AttachCurrentThread((void**)&env, &args);
        mustDetach = true; // to clean up afterwards
    }

指向方法所在的目标Java类

jclass clazz = env->FindClass("MyClazz");

指向java方法

jmethodID mid = env->GetStaticMethodID(clazz, "myJavaMethod", "()I");

调用java方法

int returnedValue = env->CallStaticintMethod(clazz, mid);

cout << "Returned value is " << returnedValue->size << endl;

这不会将未定义的引用抛给JNI_CreateJavaVM