Собственные массивы расположены в непрерывной памяти. В этом случае virStoragePoolPtr **pools
- это одиночный указатель на начало массива; и C использует свои знания о размере указателя, чтобы использовать смещения для поиска оставшихся элементов.
JNA не переводит (большинство) Java массивов в этот собственный макет. Когда это происходит, он использует четко определенные размеры, например, для примитивных массивов, таких как int[]
или для массивов Structure
, для которых JNA может рассчитать размер и выделить его с помощью метода toArray
.
Вы определили здесь массив Java:
StoragePoolPointer[] pPointerArr = new StoragePoolPointer[10];
Но вы не выделили никаких объектов Java для заполнения массива, так что это просто массив null
s. Кроме того, даже если вы заполнили массив путем итерации и установки pPointerArr[i] = new StoragePoolPointer()
, к этим указателям была бы прикреплена несмежная собственная память.
Существует (как минимум) два подхода к решению этой проблемы. Одним из них является непосредственное выделение собственной памяти с использованием класса Memory
JNA, например:
pPointerArr = new Memory(10 * Native.POINTER_SIZE);
После вызова метода virConnectListAllStoragePools()
у вас будут указатели в этом буфере, и вы можете выполнять итерацию, например: Pointer p = pPointerArr.share(i * Native.POINTER_SIZE)
будет каждый указатель при увеличении i
.
В качестве альтернативы, вы можете определить Structure
, содержащий указатель, например:
@FieldOrder({ "storagePool" })
public class StoragePoolPointer extends Structure {
public Pointer storagePool;
}
Тогда вы можете получить оба Java удобство массива и смежной собственной памяти с:
StoragePoolPointer[] pPointerArr =
(StoragePoolPointer[]) new StoragePoolPointer().toArray(10);
После заполнения массивов pPointerArr[i].storagePool
будет i
-ым указателем.
Предполагая, что 10
, который вы используете, является просто тестовым заполнителем, стандартная идиома JNA в этой ситуации состоит в том, чтобы вызвать virConnectListAllStoragePools()
один раз с нулевым указателем, чтобы получить количество используемых элементов, а затем выделить память, как я описал выше и вызовите его второй раз с буфером правильного размера (или массивом структур, поддерживаемых буфером).