2012-06-04 182 views
2

我有类在Java中称为XMLDOMDocument这个类有一些方法CreateXMLAddNodeRemoveNode等我把从C代码这种方法与Java本地接口的帮助,但这样做,我传递给我的JAVA类的C代码对象然后调用env->GetObjectClass(myclass)我从该对象中获取我的类并调用JAVA类的方法。创建C代码JAVA类

我想知道我可以做同样的事情(调用JAVA方法),而无需将我的类传递给C代码。我可以在C代码中创建JAVA类,然后调用它的方法。

编辑

如果我在C代码有JavaVM的我可以创建Java类在C代码的新实例与Java虚拟机的帮助。

编辑

我想我找到一些有用的东西Creating the Java Virtual Machine,但我想知道什么样的价值,必须stetted #define USER_CLASSPATH?如果一定要包名com.fido.android.framework.service

public class Prog { 
    public static void main(String[] args) { 
      System.out.println("Hello World " + args[0]); 
    } 
} 

#include <jni.h> 

#define PATH_SEPARATOR ';' /* define it to be ':' on Solaris */ 
#define USER_CLASSPATH "." /* where Prog.class is */ 

main() { 
    JNIEnv *env; 
    JavaVM *jvm; 
    jint res; 
    jclass cls; 
    jmethodID mid; 
    jstring jstr; 
    jclass stringClass; 
    jobjectArray args; 

#ifdef JNI_VERSION_1_2 
    JavaVMInitArgs vm_args; 
    JavaVMOption options[1]; 
    options[0].optionString = 
     "-Djava.class.path=" USER_CLASSPATH; 
    vm_args.version = 0x00010002; 
    vm_args.options = options; 
    vm_args.nOptions = 1; 
    vm_args.ignoreUnrecognized = JNI_TRUE; 
    /* Create the Java VM */ 
    res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); 
#else 
    JDK1_1InitArgs vm_args; 
    char classpath[1024]; 
    vm_args.version = 0x00010001; 
    JNI_GetDefaultJavaVMInitArgs(&vm_args); 
    /* Append USER_CLASSPATH to the default system class path */ 
    sprintf(classpath, "%s%c%s", 
      vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH); 
    vm_args.classpath = classpath; 
    /* Create the Java VM */ 
    res = JNI_CreateJavaVM(&jvm, &env, &vm_args); 
#endif /* JNI_VERSION_1_2 */ 

    if (res < 0) { 
     fprintf(stderr, "Can't create Java VM\n"); 
     exit(1); 
    } 
    cls = (*env)->FindClass(env, "Prog"); 
    if (cls == NULL) { 
     goto destroy; 
    } 

    mid = (*env)->GetStaticMethodID(env, cls, "main", 
            "([Ljava/lang/String;)V"); 
    if (mid == NULL) { 
     goto destroy; 
    } 
    jstr = (*env)->NewStringUTF(env, " from C!"); 
    if (jstr == NULL) { 
     goto destroy; 
    } 
    stringClass = (*env)->FindClass(env, "java/lang/String"); 
    args = (*env)->NewObjectArray(env, 1, stringClass, jstr); 
    if (args == NULL) { 
     goto destroy; 
    } 
    (*env)->CallStaticVoidMethod(env, cls, mid, args); 

destroy: 
    if ((*env)->ExceptionOccurred(env)) { 
     (*env)->ExceptionDescribe(env); 
    } 
    (*jvm)->DestroyJavaVM(jvm); 
} 

我也想知道传球类对象之间从Java到C和创建Java类权使用C

回答

1

的CLASSPATH差异应该定义你会以同样的方式在启动Java虚拟机时传递它。所以如果你想创建一个在com.fido.android.framework.service包内的类,你可以将生成的C可执行文件放在某个目录中,并且编译后的Java类放在com/fido/android/framework/service中子目录。这样,你不需要改变CLASSPATH定义

包的名字应该在findClass的调用进行传递:

cls = (*env)->FindClass(env, "com/fido/android/framework/service/Prog"); 
+0

@mavropovato如果我的C文件不能在同一个目录中的java类,我该如何指定路径?例如,我的C项目位于C:/projects/newproject/mycfile.c,而java类位于C:/java_projects/scr/com/Android/fido/ ..... –

+0

您可以将CLASSPATH指向所在的目录你的课堂文件已定位,但我不会推荐它。请记住,如果您在C中定义了某些内容,则需要重新编译才能更改它。对我来说最好的解决方案是将你的所有类文件打包成与你的可执行文件相关的jar文件,并将你的classpath指向那里 – mavroprovato