- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试使用 jni 从 C++ 调用 Java 方法。实际上更多的是回调(java -> c++ -> java)我通过在 .exe (c++ -> java) 中测试它来检查 c++ 程序是否有错误该程序在 Visual Studio 中完美运行。但是当我将它转换为 dll 并在 java 中使用它时失败并崩溃。我认为它与 jvm.dll 有关,因为我必须将它包含到我的 visual studio 项目中。
C++:
#include <stdio.h>
#include <jni.h>
#include <string.h>
#include "Inter.h"
JNIEnv* create_vm(JavaVM ** jvm) {
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options;
options.optionString = "-Djava.class.path=C:\\Users\\SolidSnake\\workspace\\Test\\bin"; //Path to the java source code
vm_args.version = JNI_VERSION_1_8;
vm_args.nOptions = 1;
vm_args.options = &options;
vm_args.ignoreUnrecognized = 0;
int ret = JNI_CreateJavaVM(jvm, (void**)&env, &vm_args);
if(ret < 0)
printf("\nUnable to Launch JVM\n");
return env;
}
void callMethod() {
JNIEnv *env;
JavaVM * jvm;
env = create_vm(&jvm);
jclass m;
jmethodID test;
m = env->FindClass("Main");
test = env->GetStaticMethodID(m,"callbackFromC","()V");
env->CallStaticVoidMethod(m,test);
}
Java:
public final class Main {
public native int callToC();
public static void callbackFromC() {
System.out.println("Hello from C!");
}
public static void main(String[] args) {
System.loadLibrary("Test");
new Main().callToC();
}
}
崩溃:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000007f9aed32ff8, pid=4016, tid=8228
#
# JRE version: Java(TM) SE Runtime Environment (8.0_11-b12) (build 1.8.0_11-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.11-b03 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [Test.dll+0x1a08] JNIEnv_::FindClass+0x28
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
程序是这样的 (j:callToC) -> (c:callMethod) -> (j:callbackFromC)
最佳答案
几天前我遇到了同样的问题,我找到了问题的解决方案(也许不是最好的),现在我很自豪地分享它(这个可能对将来的人有用)。
这是我只有两个项目(C++->Java)时运行良好的代码,即调用 Java 方法的 C++ 项目:
void JVM:: Init( const std:: string& javaClassesPath ) {
std:: string optionString = ( std:: string("-Djava.class.path=") + javaClassesPath );
JavaVMOption options_;
options_.optionString = const_cast<char*>( optionString.c_str() );
// initializing of JVM initial arguments:
JavaVMInitArgs arguments_;
memset( &arguments_, 0, sizeof( arguments_ ) );
arguments_.version = JNI_VERSION_1_6;
arguments_.nOptions = 1;
arguments_.options = &options_;
arguments_.ignoreUnrecognized = 0;
// creating JVM:
long status = JNI_CreateJavaVM( &jvm_, (void**)&env_, &arguments_ );
if ( status == JNI_ERR )
throw std:: exception("Error: unable to create Java Virtual Machine.\n");
FindClass("ChartBuilder");
}
这段代码是通过以下方式调用的:
JVM JChartBuilder( "D:\\Java Src\\Chart\\Chart.jar" ); // the path that will be used as classpath when creating VM (unless this path is specified it will be unable to find the class ChartBuilder)
然后 (Java->C++Java)当我得到必须使用 JNI 从那个 C++ 项目调用方法的第三个项目 (Java) 时,我遇到了一个问题,即当一个已经在当前进程中运行时我无法创建 VM。但是我们可以附加到现有的 VM!因此,可以更改上面列出的代码以满足此要求:
void JVM:: Init( const std:: string& javaClassesPath )
{
// initializing of JVM options:
std:: string optionString = ( std:: string("-Djava.class.path=") + javaClassesPath );
JavaVMOption options_;
options_.optionString = const_cast<char*>( optionString.c_str() );
// initializing of JVM initial arguments:
JavaVMInitArgs arguments_;
memset( &arguments_, 0, sizeof( arguments_ ) );
arguments_.version = JNI_VERSION_1_6;
arguments_.nOptions = 1;
arguments_.options = &options_;
arguments_.ignoreUnrecognized = 0;
// creating JVM or attaching to JVM:
long status;
/* is there any running VMs in the process? */
JavaVM* createdVMs[1] = { nullptr };
jsize numberOfVMs;
status = JNI_GetCreatedJavaVMs(createdVMs, 1, &numberOfVMs);
/* END OF is there any running VMs in the process? */
if( numberOfVMs != 0 )
{ // if VM already runs:
jvm_ = createdVMs[0]; // get the VM
jvm_->AttachCurrentThread((void**)&env_, NULL); // attach to the VM
}
else
{ // if VM does not run:
status = JNI_CreateJavaVM( &jvm_, (void**)&env_, &arguments_ );
}
if ( status == JNI_ERR )
throw std:: exception("Error: unable to create Java Virtual Machine.\n");
FindClass("ChartBuilder");
}
但这还不是全部。当运行主 Java 项目(Java->C++->Java 中的第一个)时,出现以下问题:无法找到指定的类 ChartBuilder。那就是我附加到现有的 VM,但是这个虚拟机不知道这个类的路径。请记住,当我在 C++ 中创建 VM 时,我明确指定了路径。为了解决这个问题,我现在必须在运行主 Java 项目时额外指定类路径。
就是这样。我唯一不喜欢的是在运行主 Java 项目时需要指定 ChartBuilder 的类路径,但这对我来说并不重要,尽管我想知道如何避免这种需要。也许有人知道?
关于java - 使用 jni 时出现 fatal error ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25497599/
使用Suitecrm 7.9.1 每当我尝试创建销售线索时(即提交创建销售线索表格后),我都会遇到以下错误。 每当我尝试导入csv文件时,都会遇到相同的错误。仅在实时服务器上发生此错误 Fatal e
Closed. This question is not reproducible or was caused by typos。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-to
我想在QNX上运行GoogleTestLibrary吗? 但是我收到此错误消息? ldd:FATAL: Could not load library libgtest.so.0 首先,我使用make命
尝试编译代码时,IDE 中显示的 fatal error 和非 fatal error 之间的主要区别是什么? 在这两种情况下,编译器都会显示一条错误消息,并且不会编译程序。 fatal error
当一个人试图编译代码时,在 IDE 中显示的 fatal error 和非 fatal error 之间的主要区别是什么? 在这两种情况下,编译器都会显示一条错误消息,并且程序不会被编译。 fatal
这个程序发出app: 2015/10/24 11:28:15 example.go:22: open some-crazy-non-existent-file: no such file or dir
因此,我正在从事一个项目,但是由于不断收到错误和警告,所以我遇到了一个问题。我对PHP还是很陌生,所以要保持柔和。使用PHP 5.5可以正常运行该程序。但是,当我在PHP 5.6中运行该程序时,会收到
在 WiX 安装程序中 - 如何自定义或覆盖 fatal error 对话框 ()?我想显示详细的错误消息而不是默认设置失败消息。 选项: 是否可以在 WiX 中调整 fatal error 对话框的
我正在尝试通过 Android 工具 > 重命名应用程序包 在 eclipse 中重命名我的 android 应用程序包。它正在生成错误说 A Fatal error occurred while p
我正在使用 Ubuntu 13.10 x64,我正在做一些开发人员正在使用 Windows 的项目,我最近将 git config core.eol 更改为“lf”和 core .autocrlf 为
嗯..世界上的每个服务都可以连接到我的动物园管理员,除了 kafka。下面是我在 server.properties 文件中的连接字符串 zk.connect=1.dzk.syd.druid.neo.
我正在 Java EE 7 中尝试一些东西,我已经构建了一个示例应用程序,可以在此处找到 https://github.com/kenparker/moviplex7.git . 在此过程中,我了解到
我正在尝试使用 bitbucket 中的 ssh 克隆我的存储库,但是每当我克隆存储库时,我都会得到: Connection to bitbucket.org closed by remote hos
该代码包括从一系列数字创建一个数组,以及第三个参数,其中它指示数字的步长,如果它的步长为 2,例如它来自 [1,3, 5] 代码工作正常,除非我以负数作为参数传递 step,例如NumberRange
我正在尝试在我的 ubuntu 中运行一个简单的 git pull 命令。直到几天前,它还可以完美地工作。不是它显示致命:无法访问“https://xxxxxx@bitbucket.org/repon
我知道已经有人问过类似的问题。 但是,我认为我的问题是由于我之前犯的一个错误,因此有所不同:让我解释一下。 一切都如我所愿顺利进行: git add . 我本地存储库中的所有文件。 git commi
我在尝试执行 Jenkins 作业时看到错误。 git 版本 1.8.3.1 Jenkins 2.46.2.1-滚动 我尝试将 git 升级到更高版本,但仍然通过关注 How to install l
Image of the output in the browser 我正在离线处理一个项目。我有一个名为 index.php 的文件。 现在我想在可以编辑的浏览器 sp 中启动。 但是当我尝试通过
我正在AWS的Linux机器上运行RServer Studio。 我尝试安装ModelMetrics的依赖项caret,并收到此错误: auc_.cpp:2:10: fatal error: omp.
我似乎没有重复发帖,所以这是详细信息... 当我使用 XOM(XML 对象模型,Java 库)中的非静态方法 Builder.build() 解析文档时,在 Eclipse 控制台中我得到: [Fat
我是一名优秀的程序员,十分优秀!