

![]() | Start a set with this search |
![]() | Include this search in one of my sets |
![]() | Exclude this search from one of my sets |
![]() | Permalink to these results Paste this link in email or IM: |
| Atom feed for tracking future search results Paste this URL into your reader: |
12 messages in net.java.dev.jna.usersRe: [jna-users] Generics...| From | Sent On | Attachments |
|---|---|---|
| Paul Loy | Jul 2, 2008 5:23 am | |
| Timothy Wall | Jul 2, 2008 7:13 am | |
| Timothy Wall | Jul 2, 2008 7:16 am | |
| Paul Loy | Jul 2, 2008 7:18 am | |
| Paul Loy | Aug 7, 2008 8:26 am | |
| Timothy Wall | Aug 7, 2008 10:21 am | |
| Paul Loy | Aug 14, 2008 3:18 am | |
| Timothy Wall | Aug 19, 2008 7:29 am | |
| Paul Loy | Aug 19, 2008 7:53 am | |
| Timothy Wall | Aug 19, 2008 8:01 am | |
| Alex Lam S.L. | Aug 19, 2008 10:03 am | |
| Wayne Meissner | Aug 19, 2008 5:32 pm |

![]() | Permalink for this message Paste this link in email or IM: |
![]() | Permalink for this thread Paste this link in email or IM: |
| Atom feed for this thread Paste this URL into your reader: |
| Subject: | Re: [jna-users] Generics... | Actions... |
|---|---|---|
| From: | Paul Loy (kete...@gmail.com) | |
| Date: | Aug 14, 2008 3:18:59 am | |
| List: | net.java.dev.jna.users | |
Sorry, I was talking about something similar to this:
public class GProperty<T> extends Structure implements ByReference {
public String propertyName; public T propertyData;
... }
I would like to propose a small refactor of Structure to allow us to override certain defaults. For this generic case I would like to refactor calculateSize(boolean force) as such:
int calculateSize(boolean force) { // TODO: maybe cache this information on a per-class basis // so that we don't have to re-analyze this static information each // time a struct is allocated.
structAlignment = 1; int calculatedSize = 0; Field[] fields = getClass().getFields(); // Restrict to valid fields List flist = new ArrayList(); for (int i=0;i < fields.length;i++) { int modifiers = fields[i].getModifiers(); if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) continue; flist.add(fields[i]); } fields = (Field[])flist.toArray(new Field[flist.size()]);
if (REVERSE_FIELDS) { for (int i=0;i < fields.length/2;i++) { int idx = fields.length-1-i; Field tmp = fields[i]; fields[i] = fields[idx]; fields[idx] = tmp; } } else if (REQUIRES_FIELD_ORDER) { List fieldOrder = getFieldOrder(); if (fieldOrder.size() < fields.length) { if (force) { throw new Error("This VM does not store fields in a predictable order; you must use setFieldOrder: " + System.getProperty("java.vendor") + ", " + System.getProperty("java.version")); } return CALCULATE_SIZE; } sortFields(fields, (String[])fieldOrder.toArray(new String[fieldOrder.size()])); }
for (int i=0; i<fields.length; i++) { Field field = fields[i]; int modifiers = field.getModifiers();
Class type = field.getType(); StructField structField = new StructField(); structField.isVolatile = Modifier.isVolatile(modifiers); structField.field = field; if (Modifier.isFinal(modifiers)) { field.setAccessible(true); } structField.name = field.getName(); structField.type = type;
// Check for illegal field types if (Callback.class.isAssignableFrom(type) && !type.isInterface()) { throw new IllegalArgumentException("Structure Callback field '" + field.getName() + "' must be an interface"); } if (type.isArray() && Structure.class.equals(type.getComponentType())) { String msg = "Nested Structure arrays must use a " + "derived Structure type so that the size of " + "the elements can be determined"; throw new IllegalArgumentException(msg); }
int fieldAlignment = 1; if (!Modifier.isPublic(field.getModifiers())) continue;
Object value = getField(structField); if (value == null) { if (Structure.class.isAssignableFrom(type) && !(ByReference.class.isAssignableFrom(type))) { try { value = newInstance(type); setField(structField, value); } catch(IllegalArgumentException e) { String msg = "Can't determine size of nested structure: " + e.getMessage(); throw new IllegalArgumentException(msg); } } else if (type.isArray()) { // can't calculate size yet, defer until later if (force) { throw new IllegalStateException("Array fields must be initialized"); } return CALCULATE_SIZE; } } Class nativeType = assignNativeMapper(type, value, field, structField);
structField.size = getNativeSize(nativeType, value); fieldAlignment = getNativeAlignment(nativeType, value, i==0);
// Align fields as appropriate structAlignment = Math.max(structAlignment, fieldAlignment); if ((calculatedSize % fieldAlignment) != 0) { calculatedSize += fieldAlignment - (calculatedSize % fieldAlignment); } structField.offset = calculatedSize; calculatedSize += structField.size;
// Save the field in our list structFields.put(structField.name, structField); }
if (calculatedSize > 0) { return calculateAlignedSize(calculatedSize); }
throw new IllegalArgumentException("Structure " + getClass() + " has unknown size (ensure " + "all fields are public)"); }
protected Class assignNativeMapper(Class type, Object value, Field field, StructField structField) { Class nativeType = type;
if (NativeMapped.class.isAssignableFrom(type)) { NativeMappedConverter tc = NativeMappedConverter.getInstance(type); if (value == null) { value = tc.defaultValue(); setField(structField, value); } nativeType = tc.nativeType(); structField.writeConverter = tc; structField.readConverter = tc; structField.context = new StructureReadContext(this, field); } else if (typeMapper != null) { ToNativeConverter writeConverter = typeMapper.getToNativeConverter(type); FromNativeConverter readConverter = typeMapper.getFromNativeConverter(type); if (writeConverter != null && readConverter != null) { value = writeConverter.toNative(value, new StructureWriteContext(this, structField.field)); nativeType = value != null ? value.getClass() : Pointer.class; structField.writeConverter = writeConverter; structField.readConverter = readConverter; structField.context = new StructureReadContext(this, field); } else if (writeConverter != null || readConverter != null) { String msg = "Structures require bidirectional type conversion for " + type; throw new IllegalArgumentException(msg); } } return nativeType; }
this would then allow me to create a generic superclass of Structure that could handle generics by overriding assignNativeMapper. I would be happy to put that back in to JNA if any one else would find it useful.
Paul.
On Thu, Aug 7, 2008 at 6:22 PM, Timothy Wall <twal...@dev.java.net> wrote:
On Aug 7, 2008, at 11:26 AM, Paul Loy wrote:
Hi Timothy,
Except... because a 'vanilla' instance of the nativemapped class is created by Structure (well by NativeMappedConverter.getInstance(type)). This means that we do not have the generic type applied so it tries to map to Object rather than Integer (for example if GProperty<Integer> were used). I guess I don't understand why when the data type extends NativeMapped does it then create a new instance? Why not use the instance we now have?
Can you be more specific about what code you're referring to?
--
--------------------------------------------- Paul Loy pa...@keteracel.com http://www.keteracel.com/paul







