Java JNIEnv分段错误

时间:2011-07-27 19:15:28

标签: java c++ java-native-interface jna

我正在使用它们之间的本机库来编写一些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中取消它)。

修改:

严重的任何方法:

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

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

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

目前我这样做:

加载DLL:

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吗?

明天我会回来的。

1 个答案:

答案 0 :(得分:0)

我感觉很糟糕。

Native.loadLibrary == JNA。

System.loadLibrary == JNI。

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