使用SWIG将C ++ char *转换为Java中的char []而不是String [英] Using SWIG to convert C++ char* as char[] in Java instead of String

查看:990
本文介绍了使用SWIG将C ++ char *转换为Java中的char []而不是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆