

![]() | 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: |
15 messages in net.java.dev.jna.usersRe: [jna-users] Non-direct Buffer is ...| From | Sent On | Attachments |
|---|---|---|
| Drayton Brown | Mar 11, 2009 9:22 am | |
| Daniel Kaufmann | Mar 11, 2009 6:59 pm | |
| Drayton Brown | Mar 12, 2009 5:33 am | |
| Daniel Kaufmann | Mar 12, 2009 3:05 pm | |
| Drayton Brown | Mar 13, 2009 3:28 am | |
| Drayton Brown | Mar 20, 2009 2:55 am | |
| Drayton Brown | Mar 20, 2009 4:09 am | |
| Timothy Wall | Mar 20, 2009 6:03 am | |
| Drayton Brown | Mar 20, 2009 7:28 am | |
| Drayton Brown | Mar 20, 2009 8:42 am | |
| Timothy Wall | Mar 20, 2009 9:25 am | |
| Drayton Brown | Mar 20, 2009 2:22 pm | |
| Drayton Brown | Mar 23, 2009 9:25 am | |
| Timothy Wall | Mar 23, 2009 11:10 am | |
| Drayton | Mar 23, 2009 11:47 am |

![]() | 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] Non-direct Buffer is not supported? | Actions... |
|---|---|---|
| From: | Drayton (dray...@gmail.com) | |
| Date: | Mar 23, 2009 11:47:06 am | |
| List: | net.java.dev.jna.users | |
Agh... Missed that! Sorry to bother you for something so trivial!
Thanks again Timothy!
Drayton
On 23 Mar 2009, at 18:11, Timothy Wall <twal...@dev.java.net> wrote:
native long == NativeLong != java long
On Mar 23, 2009, at 12:26 PM, Drayton Brown wrote:
Hello again!
New project, new questions!
I'm trying to represent the following C structure, which I need to pass into a C function:
typedef struct { ... long StructSize; ... union { struct {
long OrgWidth;
long OrgHeight; } Scale;
RE_POINT Offset; } Tail; ... } RE_IMAGE;
I've gone about it in the following way:
public interface RedEye extends Library { ... public static class SCALE extends Structure {
public long orgWidth; public long orgHeight; }
public static class TAIL extends Union {
public SCALE scale; public RE_POINT offset; }
public static class RE_IMAGE extends Structure {
public long structSize; // The size, in bytes, of the ::RE_IMAGE structure ( sizeof (RE_IMAGE) ). public TAIL tail;
} ... }
I've used it in my code like this:
RedEye.RE_IMAGE reImage = new RedEye.RE_IMAGE(); reImage.structSize = reImage.size(); reImage.tail.scale.orgWidth = bufferedImage.getWidth(); reImage.tail.scale.orgHeight = bufferedImage.getHeight(); reImage.tail.setType(RedEye.SCALE.class);
Unfortunately the function that I pass the structure into returns an error stating that an invalid parameter has been passed in... Could someone please let me know if if this is the correct way to deal with unions? If not a nudge in the right direction would be appreciated! Also is what I have done with the structSize variable correct? There is no documentation on the size() method, so its a little un- clear...
The method name is self documenting, unless I suppose you take it to be a verb instead of a noun... It returns the size of the structure in bytes.
Thanks again!
Drayton
2009/3/20 Drayton Brown <dray...@gmail.com> Thanks again Timothy!
You help has been invaluable!
Regards Drayton
2009/3/20 Timothy Wall <twal...@dev.java.net>
On Mar 20, 2009, at 11:43 AM, Drayton Brown wrote:
Hi all
One last request, please!
If I want to represent this in JNA how would I go about it?
typedef struct { unsigned char *data[3]; } MyStruct
"[]" binds more tightly than "*", so you have an array size 3 of "unsigned char*".
Pointer[] data = new Pointer[3]; Pointer[] data = { new Memory(x), new Memory(x), new Memory(x) };
This is what I've tried (although now I think this is completely wrong):
public static class MyStruct extends Structure { public byte[][] data = new byte[3][]; }
multidimensional arrays in Java are a totally different beast than multidimensional arrays in C.
I now suspect its something along these lines:
public static class MyStruct extends Structure { public Pointer data[]; }
But I just can't figure this one out in my head to even write it down :(
Thanks for this, I'm sure it will be the last request for a while, since this is the last thing I have to get right (I hope)
Regards Drayton
2009/3/20 Drayton Brown <dray...@gmail.com> Thanks Timothy!
That worked like a charm!
Regards Drayton
2009/3/20 Timothy Wall <twal...@dev.java.net>
Methods are looked up by function name, not by parameter or return value. Use a symbol dump tool (depends.exe on w32 or nm on linux or otool on osx) to see the symbols actually exported by your library.
If you see "_MethodName" in the C header, it may be masked by a #define, or it may be mangled by the compiler and/or linker. For example, if you use the stdcall calling convention on windows, function names have an "@NN" appended, where "NN" indicates the number of bytes of arguments to the function.
On Mar 20, 2009, at 5:55 AM, Drayton Brown wrote:
Hi all
Could someone please clarify how to map method names that have an underscore ( '_' ) as the first character?
The C function is something like this: int _MethodName( ... )
and I'm mapping it as follows in my JNA interface: public int _MethodName( ... )
In other words I'm not changing the method name at all, but I still get the following error: Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function '_MethodName'
Could someone let me know if the underscore is a special character in this case? Or is it possible that I've mapped one of the parameters incorrectly and so JNA is unable to match the function signature? (although I don't think this is the case)
Thanks in advance for any help, its much appreciated!
Regards Drayton
2009/3/13 Drayton Brown <dray...@gmail.com> Thanks Daniel your help has been most useful!
I believe that option 2 has worked out for me, although I think I will look into the direct buffer information you passed on as I believe I may be able to get some performance gains from it, as you expressed earlier.
Thanks once again,
Regards Drayton
2009/3/12 Daniel Kaufmann <dani...@gmail.com>
Please check ByteBuffer javadoc for more information regarding
Direct and Non-Direct Buffers.
(http://java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html
)
wrap creates a non direct Buffer with the passed byte array a the
backing array (meaning that when you read/write the buffer you are
reading/writing the array.
Use ByteBuffer.allocateDirect to create a direct buffer. Then use
one of the put methods of ByteBuffer to write to the buffer.
After checking jna documentation I believe, option 3 was not
correct. From jna docs: "Primitive arrays and structures as members
of a structure are overlaid on the parent structure memory." so it
is not converted to a pointer that is what you need.
Option 4 seem not to be supported, from the exception you are
getting.
Regarding the size of the image just try to print bytes.length. The
memory should have that size, since that is the parameter you pass
to the constructor.
Regards, Daniel
On Thu, Mar 12, 2009 at 9:34 AM, Drayton Brown <dray...@gmail.com
wrote:
Thanks for your timely response Daniel!
I have tried a couple of your solutions already and I thought I'd give some feedback on them, in anticipation that I may get some more help :)
Option 1:
I thought this is what I was doing in my orriginal post? Could someone possibly show me what I'm doing wrong? How does one create this direct buffer, if not by using ByteBuffer?
Option 2:
I change the JNA interface to the C stucture to the following:
public static class RE_IMAGE extends Structure { ... public Pointer data; ... }
I passed in the data as follows:
//We have to pass in a pointer to the data... ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream); byte[] bytes = byteArrayOutputStream.toByteArray(); Memory memory = new Memory(bytes.length); memory.write(0l, bytes, 0, ((Long)memory.getSize()).intValue()); reImage.data = memory;
This option is showing some promise, in that the method I call when I pass in the RE_IMAGE is executed. No Java exception is thrown with this option. However the method returns an error code stating that an invalid parameter has been passed in. I do print out the structure just before the method is executed and reImage.data is shown as follows:
Pointer data@28=allocated@0x9c36eb0 (132440 bytes)
which seems a bit small, since its a 1Mb image that I'm passing in...
As I cannot prove that the error is caused by the Memory object in this case, I'm going to continue to tinker with my implementation, hopfully I'll get lucky!
Also I'm looking into creating a MemoryOutputStream as Daniel surgested, hopefully this will the application faster, which would be really helpful!
Option 3:
I change the JNA interface to the C stucture to the following:
public static class RE_IMAGE extends Structure { ... public byte[] data; ... }
I passed in the data as follows:
RedEye.RE_IMAGE reImage = new RedEye.RE_IMAGE(); ... //We have to pass in a pointer to the data... ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream); byte[] bytes = byteArrayOutputStream.toByteArray(); reImage.data = bytes;
But unfortunately I got the following exception:
Exception in thread "main" java.lang.IllegalStateException: Array fields must be initialized at com.sun.jna.Structure.calculateSize(Structure.java:911) at com.sun.jna.Structure.allocateMemory(Structure.java:219) at com.sun.jna.Structure.ensureAllocated(Structure.java:211) at com.sun.jna.Structure.size(Structure.java:248) at jredeye.Main.main(Main.java:45)
I would take a guess that this may work if I could initialize the array in the RE_IMAGE class, but unfortunately I'm not aware of the size the array needs to be at compile time, and I expect the size will vary greatly at execution time.
Option 4:
I change the JNA interface to the C stucture to the following:
public static class RE_IMAGE extends Structure { ... public Buffer data; ... }
I passed in the data as follows:
RedEye.RE_IMAGE reImage = new RedEye.RE_IMAGE(); ... //We have to pass in a pointer to the data... ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream); byte[] bytes = byteArrayOutputStream.toByteArray(); reImage.data = ByteBuffer.wrap(bytes);
But unfortunately I got the following exception:
Exception in thread "main" java.lang.IllegalArgumentException: the type "java.nio.Buffer" is not supported as a structure field: at com.sun.jna.Structure.getNativeSize(Structure.java:1068) at com.sun.jna.Structure.calculateSize(Structure.java:945) at com.sun.jna.Structure.allocateMemory(Structure.java:219) at com.sun.jna.Structure.ensureAllocated(Structure.java:211) at com.sun.jna.Structure.size(Structure.java:248) at jredeye.Main.main(Main.java:45)
Once again thanks for the help so far, at least I have seem to have a semi-promising lead... If anyone has any more information that may be useful to me, it would be much appreciated.
regards Drayton
2009/3/12 Daniel Kaufmann <dani...@gmail.com>
As expected from the method name it indeed does not work for non direct buffers. Since your buffer is backended by a byte array it will not work. Java arrays may not be continuous in memory, so you can't get a pointer to a continuous array as expected by the native code. So you have the following options: • Copy the data to a direct buffer and then get the address • Copy the data to a JNA Memory object and then get the addre ss. • Change reImage.data type to be an array instead of a Point er. I am not 100% sure this works, but I think so. The data might be copied to an array and then copied back in the native code if t he array is non continous. • Change reImage.data type to be a Buffer instead of a Pointe r. I believe even non direct buffer are supported in this case but not sure. The data might be copied to an array and then copied ba ck in the native code if the array is non continous. For options 1 and 2 you can avoid copying the data by implementing an OutputStream that is backended by a direct buffer or a JNA Memory object instead of using ByteArrayOutputStream.
Regards, Daniel
On Wed, Mar 11, 2009 at 1:22 PM, Drayton Brown <dray...@gmail.com
wrote:
Hello all...
I've been working on trying to access a linux shared object from java for the last two weeks. Its my first time using JNA, and its been a reletively good experience. I believe that once I've solved this final problem, I will have completed the task I'm trying to do. As things are becoming quite urgent I would greatly appreciate a timely response.
This is the structure I'm having problems with:
typedef struct {
...
/** Pointer to the first scan line of the image. In case of planar format it is a pointer to an array of pointers to separate planes. */ void* Data;
...
} RE_IMAGE;
I've coded this as follows:
public interface RedEye extends Library {
public static class RE_IMAGE extends Structure {
...
public Pointer data;
...
}
}
And I'm using it like this:
RedEye.RE_IMAGE reImage = new RedEye.RE_IMAGE();
... //We have to pass in a pointer to the data... ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ImageIO.write(image_input, "jpg", byteArrayOutputStream); byte[] bytes = byteArrayOutputStream.toByteArray(); ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); Buffer buffer = (Buffer) byteBuffer; reImage.data = Native.getDirectBufferPointer(buffer); ...
Unfortunately this is throwing the following exception:
Exception in thread "main" java.lang.IllegalArgumentException: Non- direct Buffer is not supported at com.sun.jna.Native.getDirectBufferPointer(Native Method) at jredeye.Main.main(Main.java:60)
If any further detail is required, please feel free to ask. Any help or input on this would be greatly appreciated.
Regards Drayton
--------------------------------------------------------------------- To unsubscribe, e-mail: user...@jna.dev.java.net For additional commands, e-mail: user...@jna.dev.java.net







