Java JNIEnv分段错误

Str*_*ill 5 c++ java java-native-interface jna

我正在使用它们之间的本机库来做一些Java < - > .NET互操作代码,到目前为止事情进展顺利.

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

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

现在我可以来回传递变量并进行所有其他类型的通信,所以我认为我没有正确地初始化这个或什么.

我正在加载它:

this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class);     
Run Code Online (Sandbox Code Playgroud)

(我更喜欢Native.loadLibrary,因为它似乎让我可以更轻松地完成更多工作,例如多个库之间的类共享和取消并从动态JVM中取出它).

编辑:

严重的任何方法:

std::cout << "Getting version:" << std::endl;
std::cout << env->GetVersion() << std::endl;
Run Code Online (Sandbox Code Playgroud)

获取版本:

(段错误)

关于JNIEnv的任何想法会对每种方法都进行分段错误吗?这应该由JVM设置,对吗?

编辑2:

这是一个Java应用程序,它调用一个C++库,它将与.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.
Run Code Online (Sandbox Code Playgroud)

好奇,如果它是导致它的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
Run Code Online (Sandbox Code Playgroud)

所以是的,看起来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");
}
Run Code Online (Sandbox Code Playgroud)

编辑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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

java -Djava.library.path="(dir)\lib\64" EntryPoint
Getting version:
65542
Run Code Online (Sandbox Code Playgroud)

确认!我的意思是一些进展,但我不能从System.loadLibrary中加载的JVM中卸载库吗?

我基本上需要能够从JVM中取消这些库并将它们交换出来,最重要的是它们都需要"共享"一个类并且能够在运行时绑定到类...这就是为什么我去了Native.loadLibrary.

目前我这样做:

加载DLL:

this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class);
Run Code Online (Sandbox Code Playgroud)

取消它:

this.Lib = null;
Runtime.getRuntime().gc(); // Force the JVM to drop it immediately.
Run Code Online (Sandbox Code Playgroud)

I类将它们全部加载到:

public interface LibHandler extends Library{ 
    void T();
}
Run Code Online (Sandbox Code Playgroud)

有没有什么方法可以与System.loadLibrary类似地工作?

编辑6:

随意叫我笨,我正在使用JNA,而不是 JNI,这是完全不同的,也是我问题的重要来源....有没有办法用JNI做到这一点?或者我可以让JNIEnv以某种方式向JNA注册吗?我猜我可以从C++库中删除JNI并直接使用wstrings?

明天我会回来的.

Str*_*ill 0

嗯,我感觉很糟糕。

Native.loadLibrary == JNA。

System.loadLibrary == JNI。

JNA 的目的是不需要任何关于 JVM 环境的实际知识,因此您可以按原样运行本机库,因此您可以使用 char* 代替 jstring...