使用SWIG将C ++ char *转换为Java中的char []而不是String [英] Using SWIG to convert C++ char* as char[] in Java instead of String
问题描述
我试图用Java包装以下C ++函数:
I am attempting to wrap the following C++ function with Java:
char* MyClass::to_cstring();
此函数的输出作为Java String对象返回。我想它返回一个 char []
Java数组。我目前使用typemaps.i和std_string.i。有没有办法重写的行为,使std :: string仍然返回作为一个Java String
,但 char *
作为Java char数组返回?
This output of this function is returned as a Java String object. I would like it to return as a char[]
Java array. I am currently using "typemaps.i" and "std_string.i". Is there a way to override the behavior such that std::string is still returned as a Java String
, but char*
is returned as a Java char array?
如何使用Java byte []
而不是 char []
因此不必担心在8位C ++字符和Java的16位Unicode之间进行转换?
How about using Java byte[]
instead of char[]
so there is not need to worry about translating between 8-bit C++ chars and Java's 16-bit Unicode?
推荐答案
为此,您需要将默认的SWIG提供的类型标签替换为您自己的。最简单的方法是只需要写一些Javaglue:
To do this you'll need to replace the default SWIG supplied typemaps with one of your own. The simplest way to do this requires just writing some Java "glue":
%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;
}
%}
$ c> getBytes()后面的默认返回的 String
。
Does exactly what you want by calling getBytes()
behind the scenes on the default returned String
.
你也可以用你自己的一些JNI来做到这一点,以一个字节数组的形式从你的本地代码中返回:
You can also do this with some JNI of your own to return it as a byte array all the way through from your native code:
%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 glue中。
The difference here being that the mapping to byte[]
happens in the generated JNI, not in the Java glue. The glue now just proxies directly to the JNI unchanged.
我可以使用下面的Java来测试和验证这些类型:
I was able to test and verify these typemaps with the following 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()
。您可以调整此类型地图匹配的选择性或多或少。它目前不会更改大多数正常使用,您也可以使用%apply
将typemap复制到不完全匹配的其他情况。
In both these examples the typemaps match on both the return type (char *
) and the function to_cstring()
. You can adjust this typemap matching to be more or less selective. It currently doesn't change most normal usage, you can also use %apply
to copy the typemap to other cases which don't exactly match.
这篇关于使用SWIG将C ++ char *转换为Java中的char []而不是String的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!