- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我第一次尝试通过 JNI 从 C++ 加载 JVM,但我似乎无法让它工作。调用 JNI_CreateJavaVM 时出现段错误。
代码非常简单(主要是从在线示例中复制的):
#include<stdio.h>
#include<jni.h>
using namespace std;
int main(int argc, char** argv) {
printf("Initializing JVM\n");
JavaVM *jvm;
JNIEnv *env;
printf("Setting up args\n";
JavaVMInitArgs vm_args;
JavaVMOption* options = new JavaVMOption[1];
options[0].optionString = "-Djava.class.path=.";
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.ignoreUnrecognized = false;
printf("Attempting to create JVM\n");
jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if(rc != JNI_OK) {
printf("didn't work :(\n");
}
else {
printf("JVM load succeeded!\n");
jint ver = env->GetVersion();
printf("Version: %i.%i\n", (ver>>16)&0x0f, ver&0x0f);
printf("Cleaning up\n");
delete options;
jvm->DestroyJavaVM();
}
printf("Done\n");
}
我的 LD_LIBRARY_PATH 包含/usr/java/jdk1.6.0_45/jre/lib/amd64/server 这是包含 libjvm.so 库的路径。我的系统上还有一些其他的 libjvm.so 库,但它们中的大多数是用于 java 1.4 的。只有一个 jdk 1.6 libjvm.so,我也尝试使用它,结果相同。
我编译:
g++ -g -c src/jniExpCppPart.cpp -I/usr/java/jdk1.6.0_45/include -I/usr/java/jdk1.6.0_45/include/linux -o obj/jniExpCppPart.o
g++ obj/jniExpCppPart.o -L/usr/java/jdk1.6.0_45/jre/lib/amd64/server -ljvm -o exe/jniExp
当我在 gdb 中运行它时,我得到前三个打印语句,然后是:
Program received signal SIGSEGV, Segmentation fault
0x0000003249479e27 in strncmp () from /lib64/libc.so.6
(gdb) bt
#0 0x0000003249479e27 in strncmp () from /lib64/libc.so.6
#1 0x00002aaaaacd8c10 in Arguments::process_sun_java_launcher_properties(JavaVMInitArgs*) () from /usr/java/jdk1.6.0_45/jre/lib/amd64/server/libjvm.so
#2 0x00002aaaab2cfe7d in Thread::create_vm(JavaVMInitArgs*, bool*) () from /usr/java/jdk1.6.0_45/jre/lib/amd64/server/libjvm.so
#3 0x00002aaaaafcc800 in JNI_CreateJavaVM () from /usr/java/jdk1.6.0_45/jre/lib/amd64/server/libjvm.so
#4 0x0000000000400761 in main(argc=1, argv=0x7fffffffe568) at src/jni/ExpCppPart.cpp:22
我的猜测是这个问题更多地与我的环境设置方式或我如何构建可执行文件而不是代码有关。自从我真正处理链接共享库以来已经有几年了,所以我绝对有可能搞砸了一些事情。
知道我可能做错了什么吗?
更新我尝试改用 dlopen 加载库(因为我在一些使用 JNI 的 Linux 代码中看到了它)。它没有什么区别,但我想我会把它包括在这里,看看它是否给任何人提示我可能做错了什么。
我再次从未连接到互联网的系统中手动复制此内容,因此可能会有一些拼写错误。
#include<stdio.h>
#include<jni.h>
#include<dlfcn.h>
using namespace std;
//Create type for pointer to the JNI_CreateJavaVM function
typedef jint (*CreateJvmFuncPtr) (JavaVM**, void**, JavaVMInitArgs*);
//New method returns pointer to the JNI_CreateJavaVM function
CreateJvmFuncPtr findCreateJvm() {
CreateJavaFuncPtr createJvm = NULL;
void* jvmLib = dlopen("libjvm.so", RTLD_LAZY); //Get handle to jvm shared library
char* error = dlerror(); //Check for errors on dlopen
if(jvmLib = NULL || error != NULL) {
printf("FailedToLoadJVM\n");
}
//Load pointer to the function within the shared library
createJvm = (CreateJvmFuncPtr) dlsym(jvmLib, "JNI_CreateJavaVM");
error = dlerror();
if(error != NULL) {
printf("Success\n");
}
return createJVM;
}
int main(int argc, char** argv) {
printf("Initializing JVM\n");
JavaVM *jvm;
JNIEnv *env;
printf("Setting up args\n";
JavaVMInitArgs vm_args;
JavaVMOption* options = new JavaVMOption[1];
options[0].optionString = "-Djava.class.path=.";
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.ignoreUnrecognized = false;
printf("Attempting to create JVM\n");
//Old code: jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
//New code:
CreateJvmFuncPtr createJVM = findCreateJvm();
printf("findCreateJVM() returned 0x%x\n", createJVM);
jint rc = createJVM(&jvm, (void**)&env, &vm_args);
//End new code
if(rc != JNI_OK) {
printf("didn't work :(\n");
}
else {
printf("JVM load succeeded!\n");
jint ver = env->GetVersion();
printf("Version: %i.%i\n", (ver>>16)&0x0f, ver&0x0f);
printf("Cleaning up\n");
delete options;
jvm->DestroyJavaVM();
}
printf("Done\n");
}
输出(与之前类似)显示一切都成功,直到它从 JNI_CreateJavaVM 方法中抛出段错误。
Initializing JVM
Setting up args
Attempting to create JVM
Success!
findCreateJVM() returned 0xc1e70780
Segmentation fault
所以看起来至少程序可以很好地找到库/函数。但是当它被调用时出了点问题。对我来说,这表明它可能只是一个简单的 API 误解(我传递的不是我应该传递的东西),或者共享库有一些奇怪的东西。如果共享库的编译架构/字长与我的程序的编译架构/字长不同,是否可能会导致这种情况?如果是这样,我如何检查我的程序和库的目标架构?
最佳答案
好吧,这很尴尬......
我终于发现了我的问题,堆栈溢出上的任何人都无法修复它,因为我在问题中发布的代码实际上是正确的,但它与我运行的代码不同。
正如我提到的,我在没有互联网访问权限的独立系统上运行此代码,因此我不得不手动复制代码。在复制它时,我纠正了我的错误。
我的独立系统上的代码包括以下几行:
JavaVMOption* options = new JavaVMOption[1];
options[0].optionString = "-Djava.class.path=.";
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = false;
您会注意到这与我在问题中发布的代码不同。因为它缺少行:
vm_args.options = options;
所以它当然会导致段错误,因为 vm_args.options 从未设置为任何内容。
关于c++ - JNI_CreateJavaVM 上的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37572993/
我第一次尝试通过 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。我怀疑这是
我是一名优秀的程序员,十分优秀!