Using SWIG to convert C ++ char * as char [] in Java instead of String

I am trying to hide the following C ++ Java function:

char* MyClass::to_cstring(); 

This output of this function is returned as a Java String object. I would like it to be returned as an array of char[] Java. I am currently using "typemaps.i" and "std_string.i". Is there a way to override the behavior, so that std :: string still returns as a Java String , but char* returns as a Java char array?

What about using Java byte[] instead of char[] , so there is no need to worry about translating between 8-bit C ++ characters and Java-16-bit Unicode?

+4
source share
1 answer

To do this, you will need to replace the default default SWIG files with one of your own. The easiest way to do this requires simply writing a 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; } %} 

Exactly what you want by calling getBytes() behind the scenes by default, returned by String .

You can also do this with some JNI to return it as a byte array completely from your own 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; } %} 

The difference is that the mapping in byte[] takes place in the generated JNI, and not in the Java cool. Glue now simply proxies directly to JNI without changes.

I was able to validate and validate these types 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]); } } 

In both of these examples, type characters correspond to both the return type ( char * ) and the to_cstring() function. You can adjust the correspondence of this sample card to be more or less selective. Currently, it does not change most of the normal conditions of use, you can also use %apply to copy a typical map to other cases that do not exactly match.

+2
source

Source: https://habr.com/ru/post/1490481/


All Articles