twall/jna — Issue #49: Structure.java toArray() issue
Author: biggunbenny
Created: 2012-01-16 13:23:13+00:00
State: open

Hey,

I think I ran into an issue in the toArray method in class Structure:

public Structure[] toArray(Structure[] array) {
ensureAllocated();
if (this.memory instanceof AutoAllocated) {
// reallocate if necessary
Memory m = (Memory)this.memory;
int requiredSize = array.length * size();
if (m.size() < requiredSize) {
useMemory(autoAllocate(requiredSize));
}
}
array[0] = this;
int size = size();
for (int i=1;i < array.length;i++) {
array[i] = Structure.newInstance(getClass());
array[i].useMemory(memory.share(i*size, size));
array[i].read();
}

if (!(this instanceof ByValue)) {
// keep track for later auto-read/writes
this.array = array;
}

return array;
}

It looks like the first element in array is purposely skipped and set to the "this" instance. The problem is that read() is then never called for the first element and thus the fields aren't getting populated.

I have worked around this by doing:

...
// array[0] = this;
int size = size();
for (int i=0;i < array.length;i++) {
...

, but it seems like there was some thought to this, other than what I might recognize.

This is probably not the correct solution, but I believe that read() needs to get called for the "this" instance aswell. Maybe at construction.

The way Im reproducing this issue is by running WinspoolUtil.getPrinterInfo1() and test returned Structure's fields. With the repository code as it is, no fields are populated in the first element. The remaining elements are properly populated as the nature of the code suggests.