Swig: convert std :: string return type (binary) to java byte []

My situation is that I have a C ++ class (MyClass) with a method that has the following signature:

bool getSerialized(const stdString & name, std::string & serialized);

If the name is in, and serialized is out.

I got it by executing the% extend and% ignore declarations in the 'i' file as follows:

%extend MyClass{
    std::string getSerialized(const std::string & name){
        std::string res;
        $self->getSerialized(name, res);
        return res;
};
%rename("$ignore", fullname=1) "MyClass::getSerialized";

Thus, the method is used with Java as:

MyClass mc = new MyClass();
String res = mc.getSerialized("test");

But now I run into a problem, the serialized std :: string contains binary data, including the character "\ 0", which means the end of the C line, in fact the following code shows the problem in C ++:

std::string s;
s.push_back('H');
s.push_back('o');
s.push_back(0);
s.push_back('l');
s.push_back('a');
std::cout << "Length of std::string " << s.size() << std::endl;
std::cout << "CString: '" << s.c_str() << "'" << std::endl;

The above code displays:

Length of std::string 5
CString: 'Ho'

As I saw in the wrap file generated by SWIG, the wrap method actually calls c_str (), the wrapper code:

jstring jresult = 0 ;
std::string result;
result = (arg1)->getSerialized();
jresult = jenv->NewStringUTF((&result)->**c_str()**); 
return jresult;

, , Java . , () % extend, (byte []), , , . , byteArray SWIG, Java, :

byte[] serialized = mc.getSerialized("test");

: std::string , , protobuf Google ++ protobuf usage

, Swig: convert return type std::string java [], , .

SWIG 2.

+3
1

, , JNI. :

%module test

%include <std_string.i>

%typemap(jtype) bool foo "byte[]"
%typemap(jstype) bool foo "byte[]"
%typemap(jni) bool foo "jbyteArray"
%typemap(javaout) bool foo { return $jnicall; }
%typemap(in, numinputs=0) std::string& out (std::string temp) "$1=&temp;"
%typemap(argout) std::string& out {
  $result = JCALL1(NewByteArray, jenv, $1->size());
  JCALL4(SetByteArrayRegion, jenv, $result, 0, $1->size(), (const jbyte*)$1->c_str());
}
// Optional: return NULL if the function returned false
%typemap(out) bool foo {
  if (!$1) {
    return NULL;
  }
}

%inline %{
struct Bar {
  bool foo(std::string& out) {
    std::string s;
    s.push_back('H');
    s.push_back('o');
    s.push_back(0);
    s.push_back('l');
    s.push_back('a');
    out = s;
    return true;
  }
};
%}

, ++ Java , bool foo. std::string, foo, Java.

, , false.

, :

public class run { 
  public static void main(String[] argv) {
    String s = "ho\0la";
    System.out.println(s.getBytes().length);

    System.loadLibrary("test");
    Bar b = new Bar();
    byte[] bytes = b.foo();
    s = new String(bytes);
    System.out.println(s + " - " + s.length());
    assert(s.charAt(2) == 0);
  }
}

const jbyte* c_str() - , .

, , . , .

+4

All Articles