私の状況では、次のシグネチャを持つメソッドを持つ C++ クラス (MyClass) があります。
bool getSerialized(const stdString & name, std::string & serialized);
name は in 引数で、serialized は out 引数です。
次のように、「i」ファイルで %extend および %ignore 宣言を作成することで機能しました。
%extend MyClass{
std::string getSerialized(const std::string & name){
std::string res;
$self->getSerialized(name, res);
return res;
};
%rename("$ignore", fullname=1) "MyClass::getSerialized";
したがって、メソッド con は Java から次のように使用できます。
MyClass mc = new MyClass();
String res = mc.getSerialized("test");
しかし、今、私は問題に遭遇しました。シリアル化された std::string には、C 文字列の終わりを示す '\0' 文字魔女を含むバイナリ データが含まれています。実際、次のコードは 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;
上記のコードは次を表示します。
Length of std::string 5
CString: 'Ho'
SWIG によって生成されたラップ ファイルで見たように、ラップ メソッドは実際にはラップのコード c_str() を呼び出します。
jstring jresult = 0 ;
std::string result;
result = (arg1)->getSerialized();
jresult = jenv->NewStringUTF((&result)->**c_str()**);
return jresult;
したがって、予想どおり、Java で受信した文字列は切り捨てられます。では、配列の長さを事前に知らなくても、これをバイト配列 (byte[]) として返すことができるように、(おそらく) %extend 関数ラッパーを変更するにはどうすればよいでしょうか。SWIG レイヤーで byteArray を作成できれば素晴らしいので、次のように Java からメソッドを呼び出すことができます。
byte[] serialized = mc.getSerialized("test");
その他の考慮事項: バイナリ データを格納するための std::string の使用が指定されており、Google の protobuf ライブラリを使用する返される型と同様に、C++ protobuf の使用法が示されています。
タイトル Swig : convert return type std::string to java byte[]を含む非常によく似た質問がありますが、バイナリデータのケースがないため、ここで与えられた解決策は適用されません。
SWIG2を使用。