- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试熟悉 JNI API,但无法获得要编译的示例 C++ 程序。我得到了相同的示例在 linux 中编译和运行(在下面的链接中发布问题之后)但无法在 Windows 中编译它;我正在使用 mingw g++。我已将所有包含路径更改为 Windows 路径,并且 jni.h 在编译时定位,但不是 jvm.dll。
undefined reference to `JNI_CreateJavaVM' linux
以下是我尝试用来编译的命令:
g++ -g -I"C:\Program Files (x86)\Java\jdk1.7.0_21\include" -I"C:\Program Files (x86)\Java\jdk1.7.0_21\include\win32" -L"C:\Program Files (x86)\Java\jdk1.7.0_21\jre\bin\server" callJava.cpp -ljvm
和...
**same as above with the additional** : -L"C:\Program Files (x86)\Java\jdk1.7.0_21\lib"
我得到的错误是:
undefined reference to `_imp__JNI_CreateJavaVM@12'
和正在编译的cpp:
#include <jni.h>
int main(){
//firstTest();
JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
options[0].optionString = "-Djava.class.path=C:/Users/Ron/Dropbox/jni/simple/ctojava/win";
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = JNI_FALSE;
int res = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
jclass cls = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(cls, "staticInt", "(I)I");
env->CallStaticVoidMethod(cls, mid,10);
jvm->DestroyJavaVM();
}
我看了很多例子,但仍然找不到解决方案。感谢您的帮助!
更新:我非常确定找到了 jvm.dll,因为如果我删除 -L"path_to_jvm",则会收到错误消息:
mingw32/bin/ld.exe: cannot find -ljvm
就像我说的,这种方法适用于 linux,对于 windows 我还缺少什么?
最佳答案
您遇到的问题可以简单概括为名称修饰问题。链接器找不到具有给定名称的函数,因为它在 jvm.dll
中的装饰不同。
查看您遇到的初始错误:
undefined reference to '_imp__JNI_CreateJavaVM@12'
它暗示了两件事:
@12
后缀表示 JNI_CreateJavaVM
假定使用 stdcall 约定。_imp_
前缀表示该函数来自一个导入库,该库重定向到一个外部加载的 dll,该函数在其导出表中可见。jni.h
中的函数原型(prototype):
_JNI_IMPORT_OR_EXPORT_
jint JNICALL JNI_CreateJavaVM(JavaVM **, void **, void *);
预处理后大概是这样的:
__declspec(dllimport) jint __stdcall
JNI_CreateJavaVM(JavaVM **, void **, void *);
现在mingw自带的gnu链接器可以直接使用.a
、msvc的COFF格式.lib
和.dll
中的符号。在您的原始命令中,它仅在提供的搜索路径 (-L ...
) 中找到 jvm.dll
,因此它尝试使用它。
问题是在 jvm.dll
的导出表中,JNI_CreateJavaVM
函数未修饰,所以它看起来像一个 cdecl 函数.此名称与链接器期望的名称不匹配,因此您会收到 undefined reference 错误。
从 Java Dev Kit 的角度来看,它在 jdk1.7.0_21\lib\jvm.lib
中包含一个导入库,它具有此符号的正确名称修饰。您修改后的命令有效,因为通过将 -L jdk1.7.0_21\lib
添加到搜索路径,它现在链接到 jvm.lib
而不是 jvm.dll
.
关于c++ - 对 `JNI_CreateJavaVM' 窗口的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16930567/
我第一次尝试通过 JNI 从 C++ 加载 JVM,但我似乎无法让它工作。调用 JNI_CreateJavaVM 时出现段错误。 代码非常简单(主要是从在线示例中复制的): #include #inc
我找到了 http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html 是 JNI 调用函数的文档。 但
我在 JNI_CreateJavaVM 方法创建 JVM 时遇到问题,应用程序只是“程序‘[4616] VnptTokenCplusplus.exe: Native’已退出,代码为 1 (0x1)。”
JNI_CreateJavaVM 方法的第三个参数将第三个参数作为 JavaVMInitArgs 结构。 typedef struct JavaVMInitArgs {
我正在尝试启动两个调用“DispFrontEnd”函数的线程第一个线程正常结束,第二个线程无法启动 jvm.. ?? 谢谢 #include "jni.h" #include #include "S
我正在使用一个在库代码中调用 JNI_CreateJavaVM 函数的库。但是,我还需要一些 JNI 包装,并且我需要调用相同的函数 JNI_CreateJavaVM 来为我的应用程序获取 JNIEn
当我使用 Ubuntu 10.10 gcc 在 32GB 的 24 核机器上调用 JNI_CreateJavaVM() 时,它会启动 26 个线程。这似乎有点矫枉过正。在哪里可以设置创建的线程数?谢谢
我有一个 Windows MFC 应用程序: (1) 加载 JVM (JNI_CreateJavaVM()) (2) 将主线程附加到 JVM (AttachCurrentThread()) (3) 加
我有一个 C DLL,它使用 JNI 来代理对执行实际举重的底层 Java 程序的任何调用。我正在动态加载 jrockit jvm.dll 以进行函数调用。 供应商 A 有一个 C# DLL,它实际上
我在 JNI 中使用 C++ 作为我的母语。我能够创建 (c++) 共享库,并且能够在共享库的帮助下调用 java 函数。 我的过程中涉及的步骤: 1) 使用 JNI_CreateJavaVm 创建
有两种方法可以让 Android 原生 C/C++ 调用 Java 代码。 Java 应用程序首先调用 native 函数。 native 函数保存 JavaVM 和 JNIEnv,然后使用它们调用
这是在 Ubuntu 12.04/Java 7,64 位上 致力于为 WebkitGtk 版本 2 创建 java 绑定(bind)的项目。我对 WebkitGTK 的主要兴趣是 DOM 访问和操作,
在 valgrind 下编译和运行以下代码时,我一直收到“Invalid write of size 4”错误。有没有一种调用 JNI_CreateJavaVM() 的简洁方法,这样 valgrind
我正在尝试使用 JNI 从 C++ 调用 Java 方法。为此,我安装了 jdk1.7.0_51,链接到 jdk1.7.0_51\lib\jvm.lib,包括 jdk1.7.0_51\include
尝试从 native 代码调用 java 方法时出现错误。 [arm64-v8a] Compile++ : hell #include int main(){ JavaVM *j
我有 2 个项目。两者都是在 Ubuntu 64 位上的 Netbeans IDE 中创建的。 首先,我的 .so 项目实现了从其 C++ 代码调用 Java 函数。我的控制台应用程序尝试调用 .so
这发生在带有 64 位应用程序的 linux 2.6.18-238.5.1.el5 上。我的进程堆栈大小是 10MB。但是,在(成功)调用 JNI_CreateJavaVM 之后,堆栈上似乎只剩下 1
我正在开发带有 C++ 部分的 Xamarin.Android 应用程序。现在我需要从 C++ 库中直接调用 Android Java 接口(interface)。 我从 Caleb Fenton's
最近我开始在我的项目中使用JNI。这是我的代码: options[0].optionString = "-Djava.class.path=."; memset(&vm_args, 0, sizeof
在我的 C++ 应用程序中,我需要通过 JNI 调用“jar”文件内的一些 java 函数。 然而,在调用 JNI_CreateJavaVM 函数之后,我的应用程序内存增加了 3、4 GB。我怀疑这是
我是一名优秀的程序员,十分优秀!