JNI,C ++推入堆栈中的字符串

时间:2018-07-23 02:43:31

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

我的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)(内部版本   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

2 个答案:

答案 0 :(得分:1)

GetStringUTFChars返回指向实际字符串的副本的指针的可能性很低,您可以通过将其直接作为参数传递给std::string的构造函数来立即将其丢弃,从而导致内存泄漏。

您需要挂起指针才能释放指针:

const char *p = env->GetStringUTFChars(name, NULL);
std::string s(p);
env->ReleaseStringUTFChars(name, p);

请注意,即使在极少数情况下没有进行任何复制,您仍然需要调用ReleaseStringUTFChars,因为VM可能会将Java字符串固定在内存中,这可能会干扰垃圾收集器。

答案 1 :(得分: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

此外,我还考虑过使用Singleton模式,而不是使用用于堆栈的全局变量。