

![]() | 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: |
3 messages in net.java.dev.jna.usersRe: [jna-users] Mapping array of stru...| From | Sent On | Attachments |
|---|---|---|
| idmnified . | Dec 26, 2007 4:40 am | |
| Timothy Wall | Dec 26, 2007 6:09 am | |
| idmnified . | Dec 30, 2007 5:30 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] Mapping array of structures and primitive arrays | Actions... |
|---|---|---|
| From: | Timothy Wall (twal...@dev.java.net) | |
| Date: | Dec 26, 2007 6:09:13 am | |
| List: | net.java.dev.jna.users | |
On Dec 26, 2007, at 7:40 AM, idmnified . wrote:
Hi, first of all thank you for this piece of software, I think it's invaluable but for the time being I still can't get it to work properly. I have to access a third-party DLL: I begun using your library but couldn't get anyhing to work, so I decided to make myself a proxy DLL to access the main DLL and thereby expose in my own DLL easy variables to access with JNI. But after searching the mailing lists I've decided to give it another try, though I still haven't got any results (though more than before); and now I can show you the C code that works with the third-party DLL so I can point you out with more valuable info to help me (if you can!). No more talk and to the point:
The DLL's interface is showed as Fortran definitions and directives, so I think it's best if I show you the C code that I wrote that works with it:
- The protoype function I wrote that works:
typedef int (__stdcall * pCalcMulti)(short&, short&, double [], char[], short&, short&, double&, Fans[]);
Where only the last two parameters are outputs (eventhough I've seen the prototype of this function in VB as ByRef for all parameters)
Regardless of how they are used, if they are declared as by reference, you need to pass pointers (i.e. XXXByreference).
- The parameter 'Fans[]' is an array of Structure, like this (just pointing out the most significant parameters of it, as it has many):
struct Fans{ char Tipo[18]; char wrn[12]; int nrec; float eta; ...(lot's of more floats) }
Make sure your structure size matches what the native expects. Compare Structure.size() with a C call to sizeof(Fans).
After reading the tutorials and searching across the mailing lists, I got two solutions in head and some questions. First the questions:
- Do I have to initialize the variables for every parameter in the struct since they are different? Or is it managed by jni automatically? Also, do I have to allocate by myself the needed space for the structures?
You can pass in "new Fans[10]" without initializing any of the elements, either in the array or the elements themselves. If it doesn't work that way, file a bug report, because it's *supposed* to work that way.
- How may I pass from Java to native the 'char[]' type?: I've tried with char[], String and Buffer. Which one is ok? (Although buffer isn't permitted inside an Structure). The DLL needs char[] null-terminated (do i have to null-terminated them?).
byte[] corresponds to native char[]. String corresponds to native const char* (nul-terminated string). Buffer may be allowed within a struct at some point in the future, but there are some details of handling it that must be worked out.
If you need to pass a C string within a character array within a structure (i.e. in must fit within the given space), you'll need to use String.getBytes and null-terminate the array yourself. When reading back, you can use Native.toString(byte[]) to convert to String.
- Related question: how do I declare the 'char[]' in the structure in JNI so it's filled by the DLL?
byte[] buf = new byte[size];
The structure will be sized according to the allocated size of the array. After call to a function, the array elements will be updated with whatever the native code changed.
- Do I pass a C double[] with a Java double[], with a Java Buffer or a JNI PointerByReference according to the C prototype?
Yes. what you choose depends on the circumstances; you can actually declare all three in your Java interface and they'll all be directed to the same native function.
Right now I'm accessing the function this way, returning me one result(one structure) with no values (everything to 0 and null):
BPTRemote.Fans fans = new BPTRemote.Fans (); BPTRemote.Fans[] oAFans = (BPTRemote.Fans[])fans.toArray(new BPTRemote.Fans[31]);
toArray(31) will work as well.
bptDll.GET_CALCULATION_MULTIFANS (S1,S2,inData,cKey,Z1,Z2,OUT,oAFans); ... while(!exit){ oAFans[n].read(); if (oAFans[n].nrec==0) exit = true; System.out.println("Fan["+n+"]-> Tipo: "+oAFans[n].Vel); ...
So what went wrong? you don't have to do a read() after the call; JNA does that automatically. How are you indicating to the native code how many structures you're passing? How does it tell you how many it filled in?
Another solution I tried to test was the one below, although it gave me a 'nullPointerException' using Structure.useMemory :
PointerByReference pFans = new PointerByReference(); bptDll.GET_CALCULATION_MULTIFANS (S1,S2,inData,cKey,Z1,Z2,OUT,pFans); BPTRemote.Fans fans = new BPTRemote.Fans(pFans.getValue()); BPTRemote.Fans [] oAFans = (BPTRemote.Fans[])fans.toArray(31); ...
No, definitely not, unless you know the underlying code is providing you with a pointer to the array, which I don't think it is.







