未定义参考尝试从 C++ 调用 Java
我试图从 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,不要使用 gcc。默认情况下,它假定它处理的代码是用 C 编写的。当您希望它编译或链接 C++ 代码时,您应该运行 g++。这将引入 C++ 标准头文件和库。
其次,您需要包含 java 库。您链接的页面中的第 7.2.1 节对此进行了讨论。
您的命令行应该看起来更像这样:
请注意,您可能必须添加其他包含 (-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:
Note that you might have to add additional include (-I) or linker (-L) directories.