

![]() | 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: |
2 messages in net.java.dev.jna.usersRe: [jna-users] Re: users Digest 14 M...| From | Sent On | Attachments |
|---|---|---|
| Avinash Kachhy | Mar 14, 2009 8:29 am | |
| Timothy Wall | Mar 14, 2009 10:17 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] Re: users Digest 14 Mar 2009 11:45:27 -0000 Issue 267 | Actions... |
|---|---|---|
| From: | Timothy Wall (twal...@dev.java.net) | |
| Date: | Mar 14, 2009 10:17:03 am | |
| List: | net.java.dev.jna.users | |
As a structure field, String is *not* equivalent to byte[]. I'd recommend this:
MyStructure extends Structure { String data = "COM1\0"; }
This will result in a pointer field. If you use a primitive array, the bytes will be written in the memory allocated to the structure (inlined).
On Mar 14, 2009, at 11:29 AM, Avinash Kachhy wrote:
Hello I changed the String to byte[] for comport and used COM1 but I still get the same results. The first 98 should be a 0. Thanks anyway.
returned = 98 returned = -68 returned = 88 returned = 88
--- On Sat, 3/14/09, user...@jna.dev.java.net
<user...@jna.dev.java.net
wrote:
From: user...@jna.dev.java.net <user...@jna.dev.java.net
Subject: users Digest 14 Mar 2009 11:45:27 -0000 Issue 267 To: use...@jna.dev.java.net Date: Saturday, March 14, 2009, 7:45 AM Hello List,
--------- ------- C++ code | ---> | Java --------- -------
I want my c++ function to return a c++ object instance, from my c++ code to java application ?
I didn't find any examples in documentation about this. I only read about primitive types. that's why I'm asking if it's possible with JNA.
Can anyone help me? Thanks in advance
Loïc
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)<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:
1. Copy the data to a direct buffer and then get the address 2. Copy the data to a JNA Memory object and then get the address. 3. Change reImage.data type to be an array instead of a Pointer. 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 the array is non continous. 4. Change reImage.data type to be a Buffer instead of a Pointer. 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 back 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
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)<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:
1. Copy the data to a direct buffer and then get the address 2. Copy the data to a JNA Memory object and then get the address. 3. Change reImage.data type to be an array instead of a Pointer. 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 the array is non continous. 4. Change reImage.data type to be a Buffer instead of a Pointer. 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 back 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
-- http://www.facebook.com/p/Drayton_Brown/517041504
Hello
I have to work with a DLL that controls a financial printer. The DLL was originally written for NT/Win31/Win95. There is a test program and that does not seem to work on Vista too as it shows com port not open error all the time.
When I try to use the functions from the DLL, I get unexpected return codes, e.g. 68 instead of 0.
Is it not possible to use 16 bit DLLs on XP/Vista? If it is possible, is there any thing wrong below?
Thanks in advance. avinash08820 ========================================= import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; import com.sun.jna.Platform; import com.sun.jna.win32.*;
public class TestPR2API { public interface PR2Communication extends Library{
PR2Communication pr2comm = (PR2Communication) Native.loadLibrary("wpr50nt", PR2Communication.class);
public byte PRT_CHECKHW (/*void*/); // It checks hardware. public byte PRT_RESET(/*void*/); //WORD WINAPI PRT_RESET (VOID);Performs a physical Reset of the machine. public byte PRT_EJECT(/*void*/); //WORD WINAPI PRT_EJECT (VOID);Eject the paper's front. public byte PRT_CLOSECOM (/*void*/); // Closes the communications port.
/* Functions with arguments */ public byte PRT_OPENCOM(SetupPR spr); public byte PRT_WRITE(String s, byte l); } public static void main(String[] args){
final char comport[] = {'C', 'O', 'M','1'};
SetupPR spr = new SetupPR();
spr.baud = 9600; spr.stop = 1; spr.parity = 'N'; spr.data = 8; //spr.port = comport; spr.port = "COM1"; byte actual = 0; //byte expected = 0;
actual = PR2Communication.pr2comm.PRT_OPENCOM(spr); System.out.println("returned = "+ actual); actual = PR2Communication.pr2comm.PRT_CHECKHW(); System.out.println("returned = "+ actual); actual = PR2Communication.pr2comm.PRT_EJECT(); System.out.println("returned = "+ actual);
actual = PR2Communication.pr2comm.PRT_RESET(); System.out.println("returned = "+ actual); String str = "Hello Hello";byte len = (byte)str.length(); actual = PR2Communication.pr2comm.PRT_WRITE(str,len);
} } ================================================================= import java.lang.String;
import com.sun.jna.Structure; import com.sun.jna.win32.StdCallLibrary;
public class SetupPR extends Structure { //public char port[] = {'C', 'O', 'M','1'}; public String port = "com1"; public short baud = 9600; public byte parity = 'N'; public byte data = 8; public byte stop = 1; } ================================================ The above maps typedef struct (_SETUPPR
CHAR CHAR Port[5]; Port [5]; Puerta (COM1 .. COMx) Puerta (COM1 .. COMx)
USHORT Ushort Baud; Baud; Velocidad (600 .. 9600) Speed (600 .. 9600)
BYTE BYTE Parity; Parity; Paridad (N=no, O=impar, E=par) Parity (N = no, O = odd, E = par)
BYTE BYTE Data; Data; Bits Data (7 ó 8) Data bits (7 or 8)
BYTE BYTE Stop; Stop; Bits Stop (1 ó 2) Stop bits (1 or 2)
} SETUPPR; SETUPPR);
It looks like you are not mapping it correctly the structure. I think it should be public class SetupPR extends Structure { public byte port[] = new byte[5]; public short baud = 9600; public byte parity = 'N'; public byte data = 8; public byte stop = 1; } and it looks like you should copy "COM1".getBytes() to port byte array and probably make sure that the last byte is 0 . Since 0 is the default value for byte, you won't need to do anything at all for that, just don't assign the result of "COM1".getBytes() because it will have only 5 bytes, make sure you copy the bytes to the array.
It looks like it is possible to call 16 bits library from 32bit code but doesn't seem to be easy. JNA just uses LoadLibrary but to load the dll but it looks that isn't enought, look at the following link: http://support.microsoft.com/kb/123731/en-us, looks like you need to use "Universal Thunk", but I am not sure what actually involves. Regards, Daniel
On Thu, Mar 12, 2009 at 7:09 PM, Avinash Kachhy <akac...@yahoo.com> wrote:
Hello
I have to work with a DLL that controls a financial printer. The DLL was originally written for NT/Win31/Win95. There is a test program and that does not seem to work on Vista too as it shows com port not open error all the time.
When I try to use the functions from the DLL, I get unexpected return codes, e.g. 68 instead of 0.
Is it not possible to use 16 bit DLLs on XP/Vista? If it is possible, is there any thing wrong below?
Thanks in advance. avinash08820 ========================================= import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; import com.sun.jna.Platform; import com.sun.jna.win32.*;
public class TestPR2API { public interface PR2Communication extends Library{
PR2Communication pr2comm = (PR2Communication) Native.loadLibrary("wpr50nt", PR2Communication.class);
public byte PRT_CHECKHW (/*void*/); // It checks hardware. public byte PRT_RESET(/*void*/); //WORD WINAPI PRT_RESET (VOID);Performs a physical Reset of the machine. public byte PRT_EJECT(/*void*/); //WORD WINAPI PRT_EJECT (VOID);Eject the paper's front. public byte PRT_CLOSECOM (/*void*/); // Closes the communications port.
/* Functions with arguments */ public byte PRT_OPENCOM(SetupPR spr); public byte PRT_WRITE(String s, byte l); } public static void main(String[] args){
final char comport[] = {'C', 'O', 'M','1'};
SetupPR spr = new SetupPR();
spr.baud = 9600; spr.stop = 1; spr.parity = 'N'; spr.data = 8; //spr.port = comport; spr.port = "COM1"; byte actual = 0; //byte expected = 0;
actual = PR2Communication.pr2comm.PRT_OPENCOM(spr); System.out.println("returned = "+ actual); actual = PR2Communication.pr2comm.PRT_CHECKHW(); System.out.println("returned = "+ actual); actual = PR2Communication.pr2comm.PRT_EJECT(); System.out.println("returned = "+ actual);
actual = PR2Communication.pr2comm.PRT_RESET(); System.out.println("returned = "+ actual); String str = "Hello Hello";byte len = (byte)str.length(); actual = PR2Communication.pr2comm.PRT_WRITE(str,len);
} }
=================================================================
import java.lang.String;
import com.sun.jna.Structure; import com.sun.jna.win32.StdCallLibrary;
public class SetupPR extends Structure { //public char port[] = {'C', 'O', 'M','1'}; public String port = "com1"; public short baud = 9600; public byte parity = 'N'; public byte data = 8; public byte stop = 1; } ================================================ The above maps typedef struct (_SETUPPR
CHAR CHAR Port[5]; Port [5]; Puerta (COM1 .. COMx) Puerta (COM1 .. COMx)
USHORT Ushort Baud; Baud; Velocidad (600 .. 9600) Speed (600 .. 9600)
BYTE BYTE Parity; Parity; Paridad (N=no, O=impar, E=par) Parity (N = no, O = odd, E = par)
BYTE BYTE Data; Data; Bits Data (7 ó 8) Data bits (7 or 8)
BYTE BYTE Stop; Stop; Bits Stop (1 ó 2) Stop bits (1 or 2)
} SETUPPR; SETUPPR);
---------------------------------------------------------------------
To unsubscribe, e-mail: user...@jna.dev.java.net For additional commands, e-mail: user...@jna.dev.java.net
Hello! first of all, thank you for JNA! i was trying to use SWIG before, and it was giving me so many problems. working with JNA is much more comfortable.
we have a native application from which we invoke the JVM. we use JNI for C->Java and JNA for Java->C communication. The main part of the Java->C communication works through a native struct, which is filled with function pointers. The Java/JNA wrapper class is both instantiated and then passed to a Java function with JNI. This worked well when we linked the application (its actually a plugin shared library used by the application) to the jvm with -ljvm. We found out, that this is not flexible enough for our needs, and we have to load the JVM dynamically now (eg. LoadLibrary() on windows, dlopen() on unix). since we do this, we always get a SIGSEGV when trying to create the callback with JNI. To make it short, i will describe what we do with JNI in mixed C/Java code, as this shortens the code a lot. [code] // C part ... const struct ClbStruct* myNativeClb = ...; Pointer clbStructP = new IntByReference((void*)myNativeClb).getPointer().getPointer(0); MyJNAClbWrapper clbWrp = MyJNAClbWrapper.getInstance(clbStructP);
// in Java ... class MyJNAClbWrapper extends Structure implements Structure.ByReference {
public static MyJNAClbWrapper getInstance(Pointer memory) {
MyJNAClbWrapper _inst = new MyJNAClbWrapper(); _inst.useMemory(memory); _inst.read(); return _inst; } ... } [/code] through debugging the java part, i found out that the SIGSEGV happens in the line with _inst.read(); and from the JNI log, i see thta the last method cammed is Memory.free(). I guess the problem lies there, as i can not see why any native memory should be freed here. the only thing involved is a const struct pointer, that contains only function pointers, and i only want JNA to read these addresses. Is there some way to tell JNA it shall not free anything? Or is my problem a different one?
I cant see why the dynamic loading of the JVM should cause such a difference. The only idea i have is that we are doing something wrong, and the dynamic loading (different use of memory maybe), converts the problem from a memory leack to a crash.
If this is not enough information, i can supply more; just tried to keep it as short as possible.
System Details: Ubuntu Linux 8.10 32bit SUN JDK 1.6.0_10 gcc 4.3.2 Intel Duo Hi all, Since my last emails, I've made numerous changes to JNAerator (errr... *improvements*, hopefully :-D), which I summarized on these two posts : JNAerator : global variables, automatic compilation (=> java 6) + many fixes<http://ochafik.free.fr/blog/?p=126> JNAerator v0.2 : Complex C declarators support and other fixes<http://ochafik.free.fr/blog/?p=125>
These changes include : - countless fixes (structures, typedefs...) - new alternative translations for functions, using java.nio.Buffer subclasses - constructors for structures - better parsing (complex C declarators, compiler-specific modifiers, retrieval of comments...) - generation of lazily-bound globals - fixes in JNAeratorStudio (can now type brackets, undo / redo, broken jnlp file : Launch JNAeratorStudio<http://ochafik.free.fr/Java/JNAeratorStudio.jnlp> )
I also wrote a page on the project's wiki that documents the JNAeration expectable output for various kinds of input : JNAerationResults<http://code.google.com/p/jnaerator/wiki/JNAerationResults
JNAerator is still rather buggy, so I'd be highly interested in your feedback on parsing issues and / or style of generated output (for now I'm trying to follow a one-fits-all approach, but I guess I'll have to provide more JNAeration options...).
Have fun ! Cheers
-- zOlive http://ochafik.free.fr/







