未定义的引用尝试从C ++调用Java

时间:2011-09-25 17:24:00

标签: java c++ java-native-interface

我正在尝试从C ++创建Java虚拟机,并调用main方法将String参数传递给Java程序的main方法。我正在关注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]);
    }
}

这是我用来(尝试)调用JVM的C ++程序:

#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 个答案:

答案 0 :(得分:6)

首先,不要使用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)目录。