It's not entirely clear what you want to achieve exactly.
If you want to map your Buffer to a Java byte[], you can do it with a custom typemap:
%typemap(jni) Buffer "jbyteArray"
%typemap(jtype) Buffer "byte[]"
%typemap(jstype) Buffer "byte[]"
%typemap(in) Buffer {
$1.addr = (unsigned char *) JCALL2(GetByteArrayElements, jenv, $input, 0);
$1.size = JCALL1(GetArrayLength, jenv, $input);
}
%typemap(argout) Buffer {
JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *) $1.addr, 0);
}
%typemap(out) Buffer {
$result = JCALL1(NewByteArray, jenv, $1.size);
JCALL4(SetByteArrayRegion, jenv, $result, 0, $1.size, (jbyte *) $1.addr);
delete[] $1.addr;
}
%typemap(javain) Buffer "$javainput"
%typemap(javaout) Buffer { return $jnicall; }
Then C++ code like
Buffer getData();
void sendData(Buffer arg);
Will be mapped to Java:
public static byte[] getData() { ... }
public static void sendData(byte[] arg) { ... }
The difficulty with passing data to Java is to get it into the JVM heap and/or to manage the lifetime of the data. It's easy to achieve with some copying, but a truly 0-copy solution will often require a change in the C++ interface.
Complete example:
example.h
#include <stddef.h>
struct Buffer
{
unsigned char *addr;
size_t size;
};
Buffer getData();
void sendData(Buffer);
example.cxx
#include "example.h"
Buffer getData() {
Buffer rc { new unsigned char[64], 64 };
for (int i = 0; i < rc.size; ++i)
rc.addr[i] = 0x40 + i;
return rc;
}
void sendData(Buffer buf) {
// use buf.addr
}
example.i
%module example
%{
#include "example.h"
%}
%typemap(jni) Buffer "jbyteArray"
%typemap(jtype) Buffer "byte[]"
%typemap(jstype) Buffer "byte[]"
%typemap(in) Buffer {
$1.addr = (unsigned char *) JCALL2(GetByteArrayElements, jenv, $input, 0);
$1.size = JCALL1(GetArrayLength, jenv, $input);
}
%typemap(argout) Buffer {
JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *) $1.addr, 0);
}
%typemap(out) Buffer {
$result = JCALL1(NewByteArray, jenv, $1.size);
JCALL4(SetByteArrayRegion, jenv, $result, 0, $1.size, (jbyte *) $1.addr);
delete[] $1.addr;
}
%typemap(javain) Buffer "$javainput"
%typemap(javaout) Buffer { return $jnicall; }
%ignore Buffer;
%include "example.h"
test.java
class test {
public static void main(String[] args) throws Exception {
System.loadLibrary("_example");
byte[] data = example.getData();
System.out.println(new String(data));
}
}
Output:
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂