Java 调用本机C++;通过JNA实现的功能

Java 调用本机C++;通过JNA实现的功能,java,c++,string,jna,Java,C++,String,Jna,问题描述: 我的项目是java,但是我想调用C++函数,它把一个字符串作为输入,并在处理之后输出另一个字符串。我应用JNA来完成这项工作,String和Car *是java到C++的映射类型。(在处理过程中,我需要STD::string作为中间类型,详细给出了简化的代码)。 当输入字符串不长时,程序运行良好。然而,当我增加字符串的长度时(这里,我重复了6次“测试句子…”),事情开始变得奇怪。我可以看到字符串在C++程序中成功传递(成功打印出来),但是我在java中收到了一个空字符串,这意味着它不

问题描述:

我的项目是java,但是我想调用C++函数,它把一个字符串作为输入,并在处理之后输出另一个字符串。我应用JNA来完成这项工作,String和Car *是java到C++的映射类型。(在处理过程中,我需要STD::string作为中间类型,详细给出了简化的代码)。 当输入字符串不长时,程序运行良好。然而,当我增加字符串的长度时(这里,我重复了6次“测试句子…”),事情开始变得奇怪。我可以看到字符串在C++程序中成功传递(成功打印出来),但是我在java中收到了一个空字符串,这意味着它不能返回字符串。此外,每次执行while循环的次数不同(在中断循环时打印出不同的计数)

那么

1。长度有什么问题?JNA有任何限制吗?

2。我能达到我的目标吗?如何正确地在JNA中传递字符串?(顺便说一句,我尝试了指针的方法,但没有成功)

谢谢,这是我的代码和一些环境细节

C++侧代码的编写
#include<iostream>
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<<"in C:"<<input<<std::endl;
    return input.c_str();
}
JAVA端的代码>>>>>>>>>

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;
            }
        }
    }
}
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)
运行详细信息>>>>>>>>>

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;
            }
        }
    }
}
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)

<>你的C++代码有问题。您正在返回一个指向本地
std::string
的指针,该指针将在函数存在时被销毁。因此,您引入了未定义的行为

P>换句话说,即使应用程序都是C++,你的函数也会是错误的,所以它不仅仅是一个java/jn/C++问题,而是一个C++问题本身。
const char* SeudoCall(const char* str){
    std::string input(str);
    std::cout<<"in C:"<<input<<std::endl;
    return input.c_str();  // <-- this is no good.
}
const char*SeudoCall(const char*str){
std::字符串输入(str);

std::coutI试图发送一个字节[]在Java调用C++程序中,将其内容转换为C++,以使其在调用C++之后保持生存。但是,当字符串长时,JVM崩溃了。非常感谢!我用JNI替换java来解决它,但是速度减慢了。这是因为GETString UTFFARCS,ReleaseStringUTFChars或NewStringUTF?确保您运行的是代码的发布版本,而不是调试版本。我对JNA不熟悉,所以无法告诉您速度比较的差异。