#java #jna
#ява #юна #java #jna
Вопрос:
Мой машинный код — это
typedef struct driver_config {
unsigned int dllVersion;
unsigned int channelCount;
unsigned int reserved[10];
ChannelConfig channel[64];
} DriverConfig;
В Java мой класс выглядит следующим образом
public class DriverConfig extends Structure {
public int dllVersion;
public int channelCount;
public int[] reserved= new int[10];
ChannelConfig[] channel = new ChannelConfig[64];
public DriverConfig() {
super();
init();
}
private void init() {
for (int i = 0; i < channel.length; i ) {
channel[i]= new ChannelConfig();
}
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "dllVersion", "channelCount", "reserved" });
}
//toString()...
}
Объявление метода является
int getDriverConfig(DriverConfig driverConfig);
Я попытался получить доступ к методу следующим образом
DriverConfig driverConfig = new DriverConfig();
status = dll.INSTANCE.getDriverConfig(driverConfig);
System.out.println("DriverConfig Status: " status);
System.out.println(driverConfig.toString());
Если channel.length
заменяется на значение менее 50, массив инициализируется правильно, но с channel.length
это не сработало. Он даже не показал никакой ошибки, просто ничего.
Комментарии:
1.
channel
Должно быть в полевом порядке?2. Я не уверен, что это точно означает, если что-то есть в getFieldOrder(). Сначала я попытался с каналом, но затем произошла ошибка
3. И в чем была ошибка?
4. Structure.getFieldOrder() в классе DriverConfig предоставляет слишком много имен [4] ([channel, channelCount, dllVersion, зарезервировано]), чтобы соответствовать объявленным полям [3] ([channelCount, dllVersion, зарезервировано])
Ответ №1:
Ваш getFieldOrder()
массив не включает последний элемент ( channel
) вашей структуры. Я вижу в ваших комментариях, что вы пытались это сделать, но получили ошибку, потому что вы ее не объявили public
. Все элементы вашей структуры должны быть перечислены в FieldOrder
, а также объявлены public
, чтобы их можно было найти с помощью отражения.
Кроме того, с JNA 5.x (который вы должны использовать) @FieldOrder
аннотация является предпочтительной.
Вы не определили сопоставление для ChannelConfig
, но заголовок вашего вопроса и эта ссылка на API, соответствующая вашей структуре, указывают, что это вложенный структурный массив. Массивы структур должны быть выделены с использованием непрерывной памяти, либо путем непосредственного выделения собственной памяти ( new Memory()
), что требует знания размера структуры, либо с помощью Structure.toArray()
. Выделение в цикле, как вы сделали, приведет к выделению памяти для каждой новой структуры, выделенной в возможных / вероятных несмежных местоположениях в собственной памяти. Учитывая, что вы заявляете, что это, по-видимому, работает для некоторых значений, возможно, вам повезло с непрерывными распределениями, но ваше поведение, безусловно, не определено.
Поэтому ваше отображение структуры должно быть:
@FieldOrder ({"dllVersion", "channelCount", "reserved", "channel"})
public class DriverConfig extends Structure {
public int dllVersion;
public int channelCount;
public int[] reserved= new int[10];
public ChannelConfig[] channel = (ChannelConfig[]) new ChannelConfig().toArray(64);
}