要做到这一点,你需要用你自己的默认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