5

次の C++ 関数を Java でラップしようとしています。

char* MyClass::to_cstring();

この関数のこの出力は、Java String オブジェクトとして返されます。char[]Java配列として返してほしい。現在、「typemaps.i」と「std_string.i」を使用しています。std::string は引き続き Java として返されますStringchar*、Java char 配列として返されるように動作をオーバーライドする方法はありますか?

8 ビット C++ 文字と Java の 16 ビット Unicode の間の変換について心配する必要がないように byte[]、代わりにJava を使用するのはどうですか?char[]

4

1 に答える 1

3

これを行うには、SWIG が提供するデフォルトの typemap を独自のものに置き換える必要があります。これを行う最も簡単な方法は、Java の「接着剤」を記述するだけです。

%module test

%typemap(jstype) char *to_cstring() "byte[]";
%typemap(javaout) char *to_cstring() {
  return $jnicall.getBytes();
}

%inline %{
char *to_cstring() {
  static char ret[] = "hello world";
  return ret;
}
%}

getBytes()デフォルトで返されたString.

また、独自の JNI を使用して、ネイティブ コードからずっとバイト配列として返すこともできます。

%module test

%typemap(jstype) char *to_cstring() "byte[]";
%typemap(jtype) char *to_cstring() "byte[]";
%typemap(javaout) char *to_cstring() {
  return $jnicall;
}
%typemap(jni) char *to_cstring() "jbyteArray";
%typemap(out) char *to_cstring() {
  const size_t len = strlen($1);
  $result = JCALL1(NewByteArray, jenv, len);
  // TODO: check that this succeeded
  JCALL4(SetByteArrayRegion, jenv, $result, 0, len, (const jbyte*)$1);
}

%inline %{
char *to_cstring() {
  static char ret[] = "hello world";
  return ret;
}
%}

ここでの違いbyte[]は、Java グルーではなく、生成された JNI でマッピングが行われることです。接着剤は、変更されていない JNI に直接プロキシするようになりました。

次の Java を使用して、これらのタイプマップをテストおよび検証できました。

public class run {
  public static void main(String[] argv) {
    System.loadLibrary("test");
    byte[] ret = test.to_cstring();
    System.out.println(ret.length);
    System.out.println((char)ret[0]);
  }
}

char *これらの両方の例で、型マップは戻り値の型 ( ) と関数の両方で一致しますto_cstring()。この typemap マッチングを調整して、多かれ少なかれ選択的にすることができます。現在、ほとんどの通常の使用方法は変更されていません%apply。正確に一致しない他のケースに typemap をコピーするために使用することもできます。

于 2013-07-14T11:12:45.763 に答える