gpt4 book ai didi

Java JNIEnv 段错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:52:01 25 4
gpt4 key购买 nike

我正在使用它们之间的 native 库编写一些 Java<->.NET 互操作代码,到目前为止一切进展顺利。

但是由于某些原因,我无法在 JNIEnv 下运行任何方法。

System::String^ JNIStringToNet(JNIEnv * env, jstring js)
{
const char *buf = env->GetStringUTFChars(js, 0); // segfault

现在我可以来回传递变量并进行所有其他类型的通信,所以我想我没有正确初始化它或其他东西。

我是这样加载的:

this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class);     

(我更喜欢 Native.loadLibrary,因为它似乎让我可以更轻松地使用它做更多事情,例如多个库之间的类共享以及从 JVM 中动态地解除 Hook 和重新 Hook )。

编辑:

认真的任何方法:

std::cout << "Getting version:" << std::endl;
std::cout << env->GetVersion() << std::endl;

获取版本:

(段错误)

关于 JNIEnv 对每种方法的段错误有什么想法吗?这应该由 JVM 设置,对吗?

编辑 2:

这是一个调用 C++ 库的 Java 应用程序,该库将与 .NET 库交互(因此它是一个 CLR 编译的 C++ 库,如果这有任何区别的话),以限制我什至没有调用的任何外部因素.NET DLL,但只是转换返回的字符串(或者好吧......尝试)。

例如来自 Java:

this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class);
this.Lib.myCPPMethod(); // Segmentation fault during this call, JVM crashes.

想知道是否是 CLR 导致的:禁用 clr 编译并删除所有与 CLR 相关的内容,仍然如此。

编辑 3:

得到它转储:

#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000000000000, pid=1596, tid=7248
#
# JRE version: 6.0_23-b05
# Java VM: Java HotSpot(TM) 64-Bit Server VM (19.0-b09 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C 0x0000000000000000

是的,看起来 JVM 出于某种原因没有给我内存访问权限。

编辑 4:

实际调用:

JNIEXPORT jstring JNICALL Query(JNIEnv * env, jobject jobj, jstring start, jstring end)
{
std::cout << "Getting version:" << std::endl;
jint j = env->GetVersion();
return jstring("test");
}

编辑 5:

与 System.loadLibrary 一起工作:

JNIEXPORT void JNICALL Java_LibTest_T(JNIEnv *env, jobject jobj)
{
std::cout << "Getting version:" << std::endl;
jint j = env->GetVersion();
std::cout << j << std::endl;
}

输出:

java -Djava.library.path="(dir)\lib\64" EntryPoint
Getting version:
65542

确认!我的意思是取得了一些进展,但我无法从 System.loadLibrary 中加载的 JVM 卸载库,可以吗?

我基本上需要能够从 JVM 中解开这些库并将它们换出,最重要的是它们都需要“共享”一个类并能够在运行时绑定(bind)到该类......这就是我选择 Native.loadLibrary 的原因。

目前我这样做:

加载动态链接库:

this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class);

解开它:

this.Lib = null;
Runtime.getRuntime().gc(); // Force the JVM to drop it immediately.

我将它们全部加载到的类:

public interface LibHandler extends Library{ 
void T();
}

有什么方法可以类似地使用 System.loadLibrary?

编辑 6:

尽管说我笨,我使用的是 JNA,不是 JNI,这是完全不同的,也是我问题的一个巨大来源....有没有办法用 JNI 做到这一点?或者我可以让 JNIEnv 以某种方式向 JNA 注册吗?我猜我可以从 C++ 库中删除 JNI 并直接使用 wstrings 吗?

明天我会回来处理这个问题。

最佳答案

好吧,我感觉很糟糕。

Native.loadLibrary == JNA。

System.loadLibrary == JNI。

JNA 的目的是不需要任何真正的 JVM 环境知识,因此您可以按原样运行 native 库,因此您可以使用 char*... 而不是 jstring

关于Java JNIEnv 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6849931/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com