

![]() | 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: |
7 messages in net.java.dev.jna.usersRe: [jna-users] Reading back function...| From | Sent On | Attachments |
|---|---|---|
| Bob Little | Oct 13, 2008 1:34 pm | |
| Michael White | Oct 13, 2008 3:34 pm | |
| Timothy Wall | Oct 13, 2008 5:11 pm | |
| Bob Little | Oct 14, 2008 7:07 pm | |
| Timothy Wall | Oct 14, 2008 8:03 pm | |
| Bob Little | Oct 15, 2008 6:18 am | |
| Timothy Wall | Oct 15, 2008 6:45 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] Reading back function arguments | Actions... |
|---|---|---|
| From: | Timothy Wall (twal...@dev.java.net) | |
| Date: | Oct 15, 2008 6:45:00 am | |
| List: | net.java.dev.jna.users | |
On Oct 15, 2008, at 9:18 AM, Bob Little wrote:
Timothy,
Thanks for the replies. Your point about char* vs char** is well taken, and gets back to what my original question was (or should have been): Where can I find further examples of the proper use of com.sun.jna.Pointer and com.sun.jna.ptr.ByReference?
I don't think those will help you here, since what the below code is doing is not a conventional use of varargs within the C language (although it might be a common hack in glue code to other languages, I don't know).
I know that QM is using memcpy() to move data from the database to the client library. As I've said, I'm pretty much a novice C programmer so I don't know if he's using a pointer (char*) or a pointer to a pointer (char**) here.
From your description, the db code is *expecting* char*, or what was written to file would have been gibberish. Which means you can't just start sending char** instead.
I also don't know if its ok for me to post too much code here, but this is the relevant section that modifies the arguments:
/* Now update any returned arguments */
offset = offsetof(INBUFF, data.call.argdata); if (offset < buff_bytes) { va_start(ap, argc); for (i = 1; i <= argc; i++) { argptr = (ARGDATA *)(((char *)buff) + offset);
arg = va_arg(ap, char *); if (i == argptr->argno) { arg_len = LongInt(argptr->arglen); memcpy(arg, argptr->text, arg_len); arg[arg_len] = '\0';
argptr->text is being copied into the original argument (a char*/C string). This action assumes that
a) there is enough space in the original string to hold the new string (security hole, unless argptr->arglen represents the original string's length). b) the original memory is writeable (depending on the system, this could cause a memory fault); in the case of JNA, you won't have a problem because all string memory is dynamically allocated.
offset += offsetof(ARGDATA, text) + ((LongInt(argptr->arglen) + 1) & ~1); if (offset >= buff_bytes) break; } } va_end(ap);
/* */
Thanks once again for your patience here. It really is appreciated. -bob
JNA creates a dummy buffer for string arguments that allocates native memory and fills it with the equivalent of the Java String. Your code will overwrite whatever is in that buffer, but the JNA caller will ignore it because it considers the argument to be "const char*" when a String is used.
When you expect the argument to be modified, you must use byte[] or char[] (for wide strings) as the argument, then use Native.toString(byte[]/char[]) to extract the result.
On Tue, 2008-10-14 at 23:04 -0400, Timothy Wall wrote:
You'll have to figure out what mechanism your native code uses to modify the passed-in parameters. You say that the native routine gets the correct values when passed String arguments. This implies that the native function *cannot* modify those arguments; to do so it would need to receive those arguments by reference (char** instead of char*).
What converts the DB code into a shared library? There is some code that stands between the DLL interface and your DB code. What is it?







