JNI,C ++将字符串推入堆栈
Posted
技术标签:
【中文标题】JNI,C ++将字符串推入堆栈【英文标题】:JNI, C++ push string in stack 【发布时间】:2018-12-30 10:42:24 【问题描述】:我的 C++ 代码,将字符串推送到 mystack
#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;
我在使用 Java 运行时收到了以下崩溃报告,知道如何修复它吗?
Java 运行时环境检测到致命错误:
SIGSEGV (0xb) 在 pc=0x00007f29421a0207, pid=18007, tid=0x00007f2942d3e700
JRE 版本:Java(TM) SE 运行时环境 (8.0_144-b01) (build 1.8.0_144-b01) Java VM:Java HotSpot(TM) 64 位服务器 VM(25.144-b01 混合模式 linux-amd64 压缩 oops)有问题的框架:C [libc.so.6+0x97207] __libc_malloc+0x197
【问题讨论】:
【参考方案1】: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());
执行:
> java -Djava.library.path=:./lib -cp target recipeNo025.HelloWorld
Passed string: Hello
Hello
另外,我会考虑使用单例模式,而不是使用堆栈的全局变量。
【讨论】:
您好 mko,感谢您的回答。您的代码适用于一个简单的示例。我检测了从堆栈中推送和弹出的整个 JDK 和日志方法。我仍然收到错误消息。 有时,调试 JNI 可能会很痛苦。在此处查看有关调试代码的提示:youtu.be/8Cjeq4l5COU 再次感谢,我发现是并发问题,使用 mutex.lock()/unlock() 解决了这个问题。 .oOo。凉爽的!玩 JNI ;) .oOo.【参考方案2】:GetStringUTFChars
很可能返回了一个指向实际字符串的副本的指针,您立即将其作为参数传递给std::string
的构造函数,从而立即将其丢弃,从而导致内存泄漏。
您需要抓住指针才能释放它:
const char *p = env->GetStringUTFChars(name, NULL);
std::string s(p);
env->ReleaseStringUTFChars(name, p);
请注意,即使在不太可能的情况下没有复制,您仍然需要调用 ReleaseStringUTFChars
,因为 VM 可能已将 Java 字符串固定在内存中,这可能会干扰垃圾收集器。
【讨论】:
以上是关于JNI,C ++将字符串推入堆栈的主要内容,如果未能解决你的问题,请参考以下文章