Неопределенная ссылка Попытка вызова Java из C ++ - PullRequest
4 голосов
/ 25 сентября 2011

Я пытаюсь создать виртуальную машину Java из C ++ и вызвать метод main, передав аргумент String методу main программы Java.Я следую этому примеру, найденному на веб-сайте Sun: http://java.sun.com/docs/books/jni/html/invoke.html#11202

Вот простая Java-программа:

public class TestJNIInvoke
{
    public static void main(String[] args)
    {
    System.out.println(args[0]);
    }
}

Вот программа C ++, которую я использую для (попытки) вызоваJVM:

#include <jni.h>
#include <cstdlib>

using namespace std;

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

     JavaVMInitArgs vm_args;
     JavaVMOption* options = new JavaVMOption[1]; //LINE 18 ERROR
     options[0].optionString = 
           (char*)&"-Djava.class.path=C:\\Program Files\\Java\\jdk1.7.0\\bin";
     vm_args.version = JNI_VERSION_1_6;
     vm_args.nOptions = 1;
     vm_args.options = options;
     vm_args.ignoreUnrecognized = false;

     /* load and initialize a Java VM, return a JNI interface
      * pointer in env */
     res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); //LINE 26 ERROR

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

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

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

В любом случае, если я просто скомпилирую файл с:

gcc -I"c:\Program Files\Java\jdk1.7.0\include" 
    -I"c:\Program Files\Java\jdk1.7.0\include\win32" -c TestJNIInvoke.cpp

Он компилируется нормально, но когда я пытаюсь скомпилировать и связать:

gcc -I"c:\Program Files\Java\jdk1.7.0\include" 
    -I"c:\Program Files\Java\jdk1.7.0\include\win32" -g TestJNIInvoke.cpp

Я получаю две странные ошибки, которые не понимаю:

TestJNIInvoke.cpp:18: undefined reference to `operator new[](unsigned int)'
TestJNIInvoke.cpp:26: undefined reference to `_imp__JNI_CreateJavaVM@12'
collect2: ld returned 1 exit status

Я пометил строки в приведенном выше коде, где происходит ошибка, кто-нибудь сталкивался с этой проблемой раньше?

Любые идеи / ссылки будут отличными

Спасибо

1 Ответ

6 голосов
/ 25 сентября 2011

Во-первых, не используйте gcc.По умолчанию предполагается, что код, который он обрабатывает, написан на C. Когда вы хотите, чтобы он компилировал или связывал код C ++, вы должны запустить g ++.Это приведет к появлению стандартных заголовков и библиотек C ++.

Во-вторых, вам нужно включить библиотеки Java.Раздел 7.2.1 на странице, на которую вы ссылаетесь, обсуждает это.

Ваша командная строка должна выглядеть примерно так:

g++ -I"C:\Program Files\Java\jdk1.7.0\include" -L"C:\Program Files\Java\jdk1.7.0\lib" -lthread -ljava TestJNIInvoke.cpp

Обратите внимание, что вам может потребоваться добавить дополнительные include (-I) иликаталоги компоновщика (-L).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...