6 messages in net.java.dev.jna.usersRe: [jna-users] Structure mapping que...
FromSent OnAttachments
Steve NewellJul 30, 2008 11:05 am 
Michael Brewer-DavisJul 30, 2008 11:42 am 
Timothy WallJul 30, 2008 11:48 am 
Steve NewellJul 30, 2008 12:34 pm 
Timothy WallJul 30, 2008 2:48 pm 
Steve NewellJul 31, 2008 12:33 pm 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:Re: [jna-users] Structure mapping questionActions...
From:Michael Brewer-Davis (mich@tech4learning.com)
Date:Jul 30, 2008 11:42:30 am
List:net.java.dev.jna.users

JNA expects array members of structures to be inlined. To have a pointer to the array instead, you could:

- have a pointer typed structure member, and then read the array from of that pointer's address - use a ByReference member (making ByteSig implement Structure.ByReference, or creating an extension) and then using Structure.toArray to get the array

class ByteSignature extends Structure implements Structure.ByReference { ... }

class FileSignature extends Structure { public String mimeType; public int length; public ByteSignature signature;

public ByteSignature[] getSignatures() { return signature.toArray(length); } }

Steve Newell wrote:

I have the following C structs:

typedef struct ByteSignature { int offset; int length; PBYTE signature; } ByteSignature;

typedef struct FileSignature { char* mimeType; // NULL terminated string int numSignatures; // number of ByteSignatures in the signatures array ByteSignature* signatures; // array of ByteSignatures. There must be at least 1, to be valid. } FileSignature, * PFileSignature, ** PPFileSignature;

FileSignature is allocated and filled by my Java code, and passed to the dll.

I have mapped these two structures as follows:

public class ByteSignature extends Structure { public int offset; public int length; public byte[] signature;

public ByteSignature() { super(); } public ByteSignature( Pointer p ) { super(); useMemory( p ); read(); } public ByteSignature( int offset, byte... byteValues ) { super(); this.offset = offset; this.length = byteValues.length; signature = new byte[ byteValues.length ];

for( int i = 0; i < byteValues.length; i++ ) { signature[ i ] = byteValues[ i ]; } } }

public class FileSignature extends Structure { public String mimeType; public int numSignatures; public ByteSignature[] signatures;

public FileSignature() { super(); } public FileSignature( Pointer p ) { super(); useMemory( p ); read(); } }

The function I am attempting to call looks like this:

public int FindMatchingDeletedFiles( WString szDirectory, FileSignature[] fileSignatures, int numFileSignatures, PointerByReference fileHandles );

and this is how I am calling it:

public static void main( String[] args ) { Native.setProtected( true );

Undelete undelete = Undelete.INSTANCE;

PointerByReference fileHandles = new PointerByReference();

FileSignature[] signatures = createFileSignatures();

int numFiles = undelete.FindMatchingDeletedFiles( new WString( "C:\\" ), signatures, signatures.length, fileHandles );

for( int i = 0; i < numFiles; i++ ) { ... } }

However, when I run this, I get the following error:

Exception in thread "main" java.lang.IllegalStateException: Array fields must be initialized at com.sun.jna.Structure.calculateSize(Structure.java:751) at com.sun.jna.Structure.allocateMemory(Structure.java:199) at com.sun.jna.Structure.size(Structure.java:230) at com.sun.jna.Structure.getNativeSize(Structure.java:895) at com.sun.jna.Structure.getNativeAlignment(Structure.java:830) at com.sun.jna.Structure.getNativeAlignment(Structure.java:855) at com.sun.jna.Structure.calculateSize(Structure.java:783) at com.sun.jna.Structure.allocateMemory(Structure.java:199) at com.sun.jna.Structure.getPointer(Structure.java:249) at com.sun.jna.Function.convertArgument(Function.java:442) at com.sun.jna.Function.invoke(Function.java:203) at com.sun.jna.Library$Handler.invoke(Library.java:204) at $Proxy0.FindMatchingDeletedFiles(Unknown Source) at test.com.surfrecon.jna.windows.undelete.Driver.main(Driver.java:22)

Any suggestions?

Thanks,