要做到這一點,你需要用你自己的默認SWIG提供的默認類型。要做到這一點最簡單的方法只需要編寫一些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[]
發生在生成的JNI,而不是在Java膠水中。現在,粘合劑只是直接代理JNI。
我可以用下面的Java測試和驗證這些typemaps:
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()
的typemaps比賽。您可以調整此類型圖匹配以選擇性更強或更弱。它目前不會改變最常用的用法,您也可以使用%apply
將typemap複製到其他不完全匹配的情況。
至少,這必須是Java中的byte []'。 Java的'char'是一個UTF-16編碼單元。 –
謝謝。我更新了這個問題。 – dcdo