Ты рядом. К сожалению, отображение не примитивных массивов в C работает только одним способом ... вы можете отобразить полученную память в массив Java, но не отправлять массив Java в C (за исключением примитивов).
Причиной этого ограничения является то, что в C массивы являются смежными блоками памяти. Чтобы получить доступ ко второму элементу массива, вы просто смещаете число байтов, равное размеру первого элемента. Но аргумент, который вы передаете функции C, является просто указателем на начало массива.
Таким образом, ваше отображение func()
должно использовать Pointer
для аргумента массива.
Вы не описали, как вы создали свой массив Pointer[]
, но выделение каждого из них с помощью вызова new Pointer()
приведет к тому, что указатели будут разбросаны по собственной памяти, а не смежно.
Существует два основных подхода к обеспечению непрерывной памяти в зависимости от требуемого уровня абстракции.
Одним из низкоуровневых подходов является создание объекта Memory
, выделяющего достаточно места для массива Pointer
(возможно, new Memory(Native.POINTER_SIZE * numBufs)
), а затем использование setPointer()
с соответствующим кратным смещением Native.POINTER_SIZE
для сопоставления вашего массив для объекта Memory
. Затем передайте объект Memory
в функцию C.
Подход более высокого уровня состоит в том, чтобы заключить указатель в JNA Structure
, используя метод Structure.toArray()
, чтобы сделать это непрерывное выделение массива за вас. Таким образом, вы могли бы иметь это:
public class Foo extends Structure {
public Pointer bar;
}
А затем создайте массив:
Foo[] array = (Foo[]) new Foo().toArray(numBufs);
На данный момент у вас есть (непрерывный) массив собственной памяти, сопоставленный с типом JNA Pointer
. Теперь вам просто нужно назначить эти указатели на указатели указателям, прикрепленным к вашим данным:
for (int i = 0; i < numBufs; i++) {
// Assign Pointer to corresponding DirectBuffer
array[i].bar = bufs[i];
}
Тогда вы сможете передать массив в C, передав указатель первого элемента:
func(array[0].bar, numBufs);
// or equivalently
func(array[0].getPointer(), numBufs);