6 messages in net.java.dev.jna.usersRe: [jna-users] no values read after ...
FromSent OnAttachments
Kratzer, HeinrichOct 25, 2007 12:35 pm 
Timothy WallOct 25, 2007 3:14 pm 
Kratzer, HeinrichOct 26, 2007 2:02 am 
Kratzer, HeinrichOct 26, 2007 3:43 am 
Timothy WallOct 26, 2007 5:24 am 
Timothy WallOct 26, 2007 5:28 am 
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] no values read after call from a structure with bytebuffer insideActions...
From:Timothy Wall (twal@dev.java.net)
Date:Oct 26, 2007 5:24:24 am
List:net.java.dev.jna.users

This appears to be a bug in structure field handling. As an alternative you can use a Pointer for the field and assign it a Memory object.

On Oct 26, 2007, at 5:02 AM, Kratzer, Heinrich wrote:

Hallo Timothy,

thanks a lot for your quickly replay.

I tried your suggest (see below) – but it do not work.

Please see the changed structure:

public class STImage extends Structure {

/** pixels buffer : must be allocated by the caller */

public Buffer pbyBuffer = ByteBuffer.wrap(new byte[IMAGE_SIZE]);

/** Number of columns */

public short wNbCol;

/** Number of Rows */

public short wNbRow;

/** pixels buffer size (in bytes) : must be initialized by the caller to IMAGE_SIZE */

public int dwBufferSize = IMAGE_SIZE;

}

I used the structure like this:

fpPane.fpImage = new STImage();

int result = libSync.GetImage (fpPane.fpImage.getPointer(), procGetImageStatus, context.getPointer (), procImageAvailable, context.getPointer());

executing ‘new STImage’ i produces the following exception:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Native type undefined for class java.nio.ByteBuffer

at com.sun.jna.Structure.getNativeSize(Structure.java:737)

at com.sun.jna.Structure.getNativeSize(Structure.java:756)

at com.sun.jna.Structure.calculateSize(Structure.java:639)

at com.sun.jna.Structure.allocateMemory(Structure.java: 172)

at com.sun.jna.Structure.<init>(Structure.java:91)

at com.sun.jna.Structure.<init>(Structure.java:85)

at com.sun.jna.Structure.<init>(Structure.java:81)

at de.gematik.biometric.certis.STImage.<init> (STImage.java:35)

It seems, that the Structure can not allocate the Memory of a field of type Buffer.

(I am using the JNA from SVN:HEAD).

What goes wrong? Have i misunderstood your hint?

Thanks in advance for your help.

Heinrich Kratzer

Date: Thu, 25 Oct 2007 18:14:43 -0400From: Timothy Wall <twal@dev.java.net>Content-type: text/plain; charset=WINDOWS-1252; delsp=yes; format=flowedSubject: [jna-users] no values read after call from a structure with bytebuffer insi See comments below. Basically, your structure definition on the Java side is incorrect. On Oct 25, 2007, at 3:36 PM, Kratzer, Heinrich wrote: > Hallo,> > The function i use from native library takes as first argument a > pointer to a structure, as second a callback function, … .> It looks like this:> /**> > * ID3BIO_EXPORTS_API DWORD __cdecl GetImage(> > * STImage* pstImage,> > * LPID3BIO_STATUS_ROUTINE lpUpdateFunc,>

* PVOID pvUpdateContext,> > *

LPID3BIO_COMPLETION_ROUTINE lpCompletionRoutine,> > * PVOID pvCompletionContext);> > */> > int GetImage(>

Pointer pstImage,> >

LPID3BIO_STATUS_ROUTINE lpUpdateFunc,> > Pointer pvUpdateContext,> > LPID3BIO_COMPLETION_ROUTINE lpCompletionRoutine,> > Pointer pvCompletionContext);> > pstImage is a pointer to the structure, which should receive the > data. After completion the function calls assynchron the callback > function ‚lpUpdateFunc’, which works really fine. Using the context > i can access the structure. But i can not access any new data (The > data seem to be unchanged, but they are definitly not). When i > preset the buffer bevor call with ‚FF’ the VM crashes. The > behaviour is a little bit unpredictable, sometimes ‚GetImage’ > returns an error, sometimes VM crashes or nothing happens. What i > make wrong?> > Here the structure:> /**> * typedef struct> * {> * // pixels buffer : must be allocated by the caller> * BYTE* pbyBuffer;> * // Number of columns> * WORD wNbCol;> *> * // Number of Rows> * WORD wNbRow;> *> * // pixels buffer size (in bytes) : must be initialized by > the caller to IMAGE_SIZE> * DWORD dwBufferSize;> *> * } STImage, *PSTImage;> */> public class STImage extends Structure {> /** pixels buffer : must be allocated by the caller */> // public byte[] pbyBuffer = new byte[IMAGE_SIZE];> public byte[] pbyBuffer;This field needs to be a Pointer or Buffer. Using a primitive array makes the structure allocate memory for it in- line, making your structure as large as your buffer.> > /** Number of columns */> public short wNbCol;> > /** Number of Rows */> public short wNbRow;> > /** pixels buffer size (in bytes) : must be initialized by the > caller to IMAGE_SIZE (public final int IMAGE_SIZE = (int)128400) */> public int dwBufferSize;> > public STImage() {> super (Structure.CALCULATE_SIZE, Structure.ALIGN_MSVC);> ALIGN_MSVC is the default on windows, so the argument is redundant here.

pbyBuffer = new byte[IMAGE_SIZE];>

dwBufferSize = pbyBuffer.length;Instead, use ByteBuffer.wrap(new byte[IMAGE_SIZE]; it's also better style to initialize the fields inline rather than in the ctor, unless you need to do some complex initialization. If the size can't be calculated by the Structure ctor, size calculation and memory allocation are deferred until the structure is actually passed to a function, so in most cases you don't have to do it explicitly in your subclass ctor.