JNI,C++;堆栈中的推字符串 < P> C++代码,将字符串推到MyStase #include <iostream> #include <stack> #include "NativeLogger.h" std::stack<std::string> mystack; JNIEXPORT void JNICALL Java_NativeLogger_push(JNIEnv *env, jobject obj,jstring name) { std::string s = env->GetStringUTFChars(name, 0); mystack.push(s); return; } JNIEXPORT void JNICALL Java_NativeLogger_pop(JNIEnv *env, jobject obj) { mystack.pop(); return; } #包括 #包括 #包括“NativeLogger.h” std::stack mystack; JNIEXPORT void JNICALL Java_NativeLogger_push(JNIEnv*env、jobject obj、jstring名称) { std::string s=env->GetStringUTFChars(名称,0); mystack.push(s); 返回; } JNIEXPORT void JNICALL Java_NativeLogger_pop(JNIEnv*env,jobject obj) { mystack.pop(); 返回; }
我在用Java运行时收到了一份跟踪崩溃报告,你知道如何修复它吗 Java运行时环境检测到一个致命错误: 在pc=0x00007f29421a0207,pid=18007时的SIGSEGV(0xb), tid=0x00007f2942d3e700 JRE版本:Java(TM)SE运行时环境(8.0_144-b01)(构建 1.8.0_144-b01)Java虚拟机:Java热点(TM)64位服务器虚拟机(25.144-b01混合模式linux-amd64压缩oops)有问题的帧:C [libc.so.6+0x97207]\uu libc\u malloc+0x197JNI,C++;堆栈中的推字符串 < P> C++代码,将字符串推到MyStase #include <iostream> #include <stack> #include "NativeLogger.h" std::stack<std::string> mystack; JNIEXPORT void JNICALL Java_NativeLogger_push(JNIEnv *env, jobject obj,jstring name) { std::string s = env->GetStringUTFChars(name, 0); mystack.push(s); return; } JNIEXPORT void JNICALL Java_NativeLogger_pop(JNIEnv *env, jobject obj) { mystack.pop(); return; } #包括 #包括 #包括“NativeLogger.h” std::stack mystack; JNIEXPORT void JNICALL Java_NativeLogger_push(JNIEnv*env、jobject obj、jstring名称) { std::string s=env->GetStringUTFChars(名称,0); mystack.push(s); 返回; } JNIEXPORT void JNICALL Java_NativeLogger_pop(JNIEnv*env,jobject obj) { mystack.pop(); 返回; },java,c++,java-native-interface,Java,C++,Java Native Interface,我在用Java运行时收到了一份跟踪崩溃报告,你知道如何修复它吗 Java运行时环境检测到一个致命错误: 在pc=0x00007f29421a0207,pid=18007时的SIGSEGV(0xb), tid=0x00007f2942d3e700 JRE版本:Java(TM)SE运行时环境(8.0_144-b01)(构建 1.8.0_144-b01)Java虚拟机:Java热点(TM)64位服务器虚拟机(25.144-b01混合模式linux-amd64压缩oops)有问题的帧:C [libc.s
很可能
GetStringUTFChars
返回了一个指向实际字符串副本的指针,您通过将其作为参数直接传递给std::string
的构造函数,立即丢弃了该指针,从而导致内存泄漏
您需要抓住指针才能释放它:
const char *p = env->GetStringUTFChars(name, NULL);
std::string s(p);
env->ReleaseStringUTFChars(name, p);
请注意,即使在不太可能的情况下没有复制,您仍然需要调用ReleaseStringUTFChars
,因为VM可能已将Java字符串固定在内存中,这可能会干扰垃圾收集器。Java代码:
package recipeNo025;
public class HelloWorld {
public static native void pushString(String s);
public static native String popString();
static {
System.loadLibrary("HelloWorld");
}
public static void main(String[] args) {
HelloWorld.pushString("Hello");
System.out.println(HelloWorld.popString());
}
}
C++代码
#include <iostream>
#include <stack>
#include "jni.h"
#include "recipeNo025_HelloWorld.h"
std::stack<std::string> mystack;
JNIEXPORT void JNICALL Java_recipeNo025_HelloWorld_pushString
(JNIEnv *env, jclass obj, jstring str) {
// we have to get string bytes into C string
const char *c_str;
c_str = env->GetStringUTFChars(str, NULL);
if(c_str == NULL) {
return;
}
std::cout << "Passed string: " << c_str << std::endl;
std::string my_string(c_str);
mystack.push(my_string);
// after using it, remember to release the memory
env->ReleaseStringUTFChars(str, c_str);
}
JNIEXPORT jstring JNICALL Java_recipeNo025_HelloWorld_popString
(JNIEnv *env, jclass obj) {
std::string s = mystack.top();
mystack.pop();
return env->NewStringUTF(s.c_str());
}
另外,我会考虑使用单例模式,而不是为堆栈使用全局变量。嗨,mko,谢谢你的回答。您的代码适用于一个简单的示例。我检测了从堆栈中推送和弹出的整个JDK和日志方法。我仍然会出错。有时候,调试JNI可能会很痛苦。在这里查看有关调试代码的提示:再次感谢,我发现这是并发问题,使用mutex.lock()/unlock()解决了这个问题..oo。酷!享受JNI带来的乐趣;)。哦。
> java -Djava.library.path=:./lib -cp target recipeNo025.HelloWorld
Passed string: Hello
Hello