2012-06-04 1 views
2

У меня есть класс в Java называется XMLDOMDocument этот класс есть некоторые методы CreateXML, AddNode, RemoveNode и т.д. Я называю это методы из кода C с помощью Java Native Interface, но для этого, что я проходит объект кода C моего класса JAVA, а затем вызывая env->GetObjectClass(myclass). Я получаю свой класс от этого объекта и вызывают методы класса JAVA.Создать класс JAVA из кода C

Я хочу знать, могу ли я сделать то же самое (вызывать методы JAVA), не передавая мой класс C-коду. Могу ли я создать класс JAVA прямо в коде C, а затем вызвать его методы.

Edited

И если у меня есть JavaVM в моем коде C можно создать новый экземпляр класса JAVA в коде C с помощью этой виртуальной машины Java.

Edited

Я думаю, что я нашел что-то полезное 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); 
} 

Я также хотел бы знать разницу между объектом прохождения класса с Явы в 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 и если мой с файл не может быть в том же каталоге, что и класс Java , как я должен указать путь? Например, проект my c находится в C: /projects/newproject/mycfile.c, а класс java - в C:/java_projects/scr/com/android/fido/..... –

+0

Вы можете указать свой CLASSPATH в каталог, где ваши файлы классов расположены, но я бы не рекомендовал его. Помните, что в C, если вы #define что-то, вам нужно перекомпилировать, чтобы изменить его. Лучшим решением для меня было бы упаковать все файлы класса в банке относительно вашего исполняемого файла и указать свой путь к классам там – mavroprovato