简体   繁体   中英

JNI Call java method from c program

I need to call java method from c program. i have tried below code to call the java method through Java native interface but facing issues while compilation. im new to C and have experience in java. so, im not able to think myself what is happening while creating JVM.

Below is the code.

CTest.c
#include <stdio.h>
#include <jni.h>

JNIEnv* create_vm() {
    JavaVM* jvm;
    JNIEnv* env;
    JavaVMInitArgs args;
    JavaVMOption options[1];
    args.version = JNI_VERSION_1_6;
    args.nOptions = 1;
    options[0].optionString = "-Djava.class.path=D:\\Ashish_Review\\JNI\\src";
    args.options = options;
    args.ignoreUnrecognized = JNI_FALSE;

    JNI_CreateJavaVM(&jvm, (void **)&env, &args);
    return env;
}

void invoke_class(JNIEnv* env) {
    jclass helloWorldClass;
    jmethodID mainMethod;
    jobjectArray applicationArgs;
    jstring applicationArg0;

    helloWorldClass = (*env)->FindClass(env, "HelloWorld");

    mainMethod = (*env)->GetStaticMethodID(env, helloWorldClass, "main", "([Ljava/lang/String;)V");

    applicationArgs = (*env)->NewObjectArray(env, 1, (*env)->FindClass(env, "java/lang/String"), NULL);
    applicationArg0 = (*env)->NewStringUTF(env, "From-C-program");
    (*env)->SetObjectArrayElement(env, applicationArgs, 0, applicationArg0);

    (*env)->CallStaticVoidMethod(env, helloWorldClass, mainMethod, applicationArgs);
}


int main(int argc, char **argv) {
    JNIEnv* env = create_vm();
    invoke_class( env );
}


C:\Users\Desktop\tcc>tcc C:\TurboC++\Disk\TurboC3\BIN\CTest.c -I "C:\Program Files\Java\jdk1.6.0_16\include" -I "C:\Program Files\Java\jdk1.6.0_16\include\win32" -shared -o CTest.dll
tcc: undefined symbol '_JNI_CreateJavaVM@12'

please help me out.

The error message is about the linking stage, not compilation - you have included the header file, but to create the executable you have to specify the .a (library files) also.

You have to link with JVM's library (add some reference to libjvm.a to the tcc's command line).

If you don't have a precompiled jvm.lib file for TurboC++, there is another option - link with the jvm.dll file and export all the methods from JVM manually. This uses the LoadLibrary/GetProcAddress functions.

For a short sample (sorry, couldn't find the entire export source code), look at this:

/* load library */
HMODULE dll = LoadLibraryA("jvm.dll");

/* declare a function pointer and initialize it with the "pointer" to dll's code */
JNI_CreateJavaVM_func JNI_CreateJavaVM_ptr = GetProcAddress(dll, "JNI_CreateJavaVM");

Later use the JNI_CreateJavaVM_ptr instead of JNI_CreateJavaVM. Also you'll have to declare the JNI_CreateJavaVM_func type - you might just copy the signature from "jni.h"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM