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?
明天我会回来的.
嗯,我感觉很糟糕。
Native.loadLibrary == JNA。
System.loadLibrary == JNI。
JNA 的目的是不需要任何关于 JVM 环境的实际知识,因此您可以按原样运行本机库,因此您可以使用 char* 代替 jstring...