未定义参考尝试从 C++ 调用 Java

发布于 2024-12-06 13:07:03 字数 2760 浏览 0 评论 0原文

我试图从 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

我在上面的代码中标记了发生错误的行,有没有人遇到过这个问题前?

任何想法/链接都会很棒

谢谢

I am trying to create a Java virtual machine from C++ and invoke the main method passing a String argument to the main method of the Java program. I am following this example found on Sun's website: http://java.sun.com/docs/books/jni/html/invoke.html#11202

Here is the simple Java Program:

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

Here is the C++ program I am using to (try to) invoke the 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();
}

Anyway If I just compile the file with:

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

It compiles fine, but when I try to compile and link:

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

I get two weird errors that I don't understand:

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

I marked the lines in the above code where the error is occuring, has anyone encountered this problem before?

Any ideas/links would be great

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

西瓜 2024-12-13 13:07:03

首先,不要使用 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

请注意,您可能必须添加其他包含 (-I) 或链接器 (-L) 目录。

First, don't use gcc. By default, it assumes the code it's handling is written in C. When you want it to compile or link C++ code, you should run g++. This will bring in the C++ standard headers and libraries.

Second, you need to include the java libraries. Section 7.2.1 in the page you linked discusses this.

Your command line should look more like this:

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

Note that you might have to add additional include (-I) or linker (-L) directories.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文