Используйте SWIG, чтобы связать C беззнаковый указатель char с Java ArrayList или структурой коллекции - PullRequest
1 голос
/ 09 декабря 2011

Если у меня есть функция C (см. Ниже), которая возвращает беззнаковый указатель на массив. Как бы вы указали SWIG связываться с типом данных Java ArrayList для getFoo (). Я не уверен, что ArrayList возможен, возможно, массив (String [] в этом случае). Я хочу, чтобы тип возвращаемого Java getFoo был как можно более универсальным, поскольку C getFoo может возвращать массив int, double, char..etc.

   unsigned char * getFoo(int32_t *length){

    static unsigned char foo[44];
    foo[0]='a';
    foo[1]='b';
    foo[2]='c';
    foo[3]='d';
    return foo;
}

1 Ответ

1 голос
/ 09 декабря 2011

Самый общий ответ - представить результат в виде несвязанного массива C в Java:

%module test

%include "carrays.i"
%array_class(unsigned char, ucArray);

unsigned char *getFoo();

Генерирует класс с именем ucArray, который получает и устанавливает для определенного индекса. Он неограниченный, с той же семантикой, что и массивы C, но легкий и удобный. Поскольку он не ограничен, вы можете вызывать Undefined Behavior из Java, и он не имеет границ, что делает невозможным использование в качестве Iterator или Collection.

.

Если ваш массив завершен до NULL / 0, было бы достаточно просто использовать %extend для реализации интерфейса Java Iterable, грубый, непроверенный пример:

%typemap(javainterfaces) ucArray "java.lang.Iterable<Short>"
%typemap(javacode) ucArray %{
  public java.util.Iterator<Short> iterator() {
    return new java.util.Iterator<Short>() {
      private int pos = 0;
      public Short next() {
        // Mmmm autoboxing!
        return getitem(pos++);
      }
      public void remove() {
        throw new UnsupportedOperationException();
      }
      public boolean hasNext() {
        // Check if we're at the end. A NULL/0 element represents the end
        return getitem(pos) != 0;
      }
    };
  }
%}

Это нужно куда-то сделать до вызова макроса %array_class. В нем говорится, что наш класс ucArray будет реализовывать Iterable, а затем реализует этот интерфейс, используя анонимный внутренний класс в методе iterator() (единственный метод интерфейса Iterable) для реализации интерфейса Iterator.

...