java返回值类型不确定,通过JNA调用本地C ++函数的不确定性返回值(字符串类型)...

problem description:

My project is JAVA but I want to call a C++ function, which takes a string as input and output another string after process. I apply JNA to do this work, and String and char* are mapping types from JAVA to C++.(During the processing, I need std::string as intermediate type, the simplyfied code is given out in detail.)

The program runs well, when the input string is not long. However, when I increase the length of the string(here, I duplicate "test sentence..." for 6 times), things began strange. I can see the string is pass in C++ program(successfully print out), BUT I received an empty string in JAVA, which means it fails to return the string. What's more, the times of while loop is different on each excution(print out different count when break the loop).

Then,

1. What's wrong with the length? Is there any limitation in JNA?

2. Can I reach my goal and how to pass string in JNA correctly?(BTW, I tried Pointer things, but it doesn't work)

Thanks ahead, here is my code and some enviroment details

CODE ON C++ SIDE>>>>>>>>>>>test.cpp

#include

using namespace std;

extern "C" __attribute__((visibility("default"))) const char* SeudoCall(const char* input);

const char* SeudoCall(const char* str){

std::string input(str);

std::cout<

return input.c_str();

}

COMPILE C++ LIBRARY>>>>>>>>>

g++ test.cpp -fpic -shared -o libtest.so

CODE ON JAVA SIDE>>>>>>>>>>>

import com.sun.jna.Library;

import com.sun.jna.Native;

public class TestSo {

public interface LgetLib extends Library {

LgetLib INSTANCE = (LgetLib) Native.loadLibrary("test", LgetLib.class);

String SeudoCall(String input);

}

public String SeudoCall(String input){

return LgetLib.INSTANCE.SeudoCall(input);

}

public static void main(String[] args) {

TestSo ts = new TestSo();

String str = "test sentence...test sentence...test sentence...test sentence...test sentence...test sentence...";

String retString;

int count=0;

while(true){

System.out.println("count:"+(++count));

retString=ts.SeudoCall(str);

System.out.println("in JAVA:"+retString);

if(retString.equals("")){

System.out.println("break");

break;

}

}

}

}

RUN DETAIL>>>>>>>>>>>

Intel Core i7-4790 3.60GHz

gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

JNA 4.1.0

java version "1.8.0_31"

Java(TM) SE Runtime Environment (build 1.8.0_31-b13)

Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)

解决方案

You have a problem with your C++ code right away. You are returning a pointer to a local std::string that will be destroyed when the function exists. Thus you are introducing undefined behavior.

In other words, your function would be buggy even if the application were all C++, so it isn't solely a Java/JNA/C++ issue, but a C++ issue in itself.

const char* SeudoCall(const char* str){

std::string input(str);

std::cout<

return input.c_str(); //

}

The c_str() is tied to the local variable input. When the function exits, the destructor for input takes place, taking along with it the c_str() that represented the string.

To fix this, you have to return a string back to Java that will be "alive" after the function returns. I do not know JNA, but for JNI, you use the JNI NewStringUTF function to create a string that will be returned as a jstring.

Maybe this link will help you:

The program runs well, when the input string is not long. However,

when I increase the length of the string(here, I duplicate "test

sentence..." for 6 times), things began strange. I can see the string

is pass in C++ program(successfully print out), BUT I received an

empty string in JAVA, which means it fails to return the string.

What's more, the times of while loop is different on each

excution(print out different count when break the loop).

What you are witnessing is undefined behavior. The pointer returned from your C++ function may be pointing to the memory that holds the characters, but it is not to be relied on, as your testing is showing you.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值