Передача буфера между Java и C ++ с использованием SWIG - PullRequest
0 голосов
/ 15 мая 2018

Я хочу передать сегмент информации (например, 1024 байта памяти) между Java и C ++, используя SWIG. Структура, определенная в C ++, выглядит следующим образом:

struct Buffer
{
    unsigned char *addr;
    size_t        size;
}

Как мне написать файл интерфейса SWIG для этой цели?

1 Ответ

0 голосов
/ 17 мая 2018

Не совсем ясно, чего именно вы хотите достичь.

Если вы хотите сопоставить Buffer с Java byte[], вы можете сделать это с помощью пользовательской карты типов:

%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; }

Затем код C ++, такой как

  Buffer getData();
  void sendData(Buffer arg);

, будет сопоставлен с Java:

  public static byte[] getData() { ... }
  public static void sendData(byte[] arg) { ... }

Сложность передачи данных в Java заключается в том, чтобы поместить их в кучу JVM и / илиуправлять временем жизни данных.Этого легко достичь с помощью некоторого копирования, но для решения с подлинным 0-копированием часто требуется изменение интерфейса C ++.

Полный пример:

пример.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));
    }
}

Выход :

@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂
...