

![]() | 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.usersincorrect call-by-value semantics?| From | Sent On | Attachments |
|---|---|---|
| David Monniaux | Mar 13, 2008 8:01 am | |
| David Monniaux | Mar 13, 2008 8:49 am | |
| Timothy Wall | Mar 13, 2008 10: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: | incorrect call-by-value semantics? | Actions... |
|---|---|---|
| From: | David Monniaux (Davi...@imag.fr) | |
| Date: | Mar 13, 2008 8:49:12 am | |
| List: | net.java.dev.jna.users | |
Platform: IA32 Linux, if that matters.
There is I think something wrong with the way that JNA handles objects that are returned-by-value by a C function (here, f1), then later passed by reference to another C function (here, f2). These objects carry a dynamic type implementing the interface Structure.ByValue, even though their static type does not. When JNA calls the f2 function, it apparently tests whether to pass the parameter by value or by reference not according to the type signature of f2 (type Foobar vs type Foobar.ByValue) but according to the dynamic type of the parameter.
As a consequence the following program prints out: $ java -Djna.library.path=. -classpath .:jna.jar CallByValueBug 42 0x812ab58->x = 5 Called by value!!!
The same f2 function is first called by reference (correct) but f2(vRet) calls it by value...
Current workaround: any object returned by value (of type Foobar.ByValue) should be copied field-by-field into an object of type Foobar before attempting any further calls.
Regards, DM
import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Structure;
public class CallByValueBug { public static class Foobar extends Structure { public int x; public static class ByValue extends Foobar implements Structure.ByValue {} }
public interface CallByValueBugLibrary extends Library { CallByValueBugLibrary INSTANCE = (CallByValueBugLibrary) Native.loadLibrary("callbyvaluebug", CallByValueBugLibrary.class);
Foobar.ByValue f1(); void f2(Foobar v); }
public static void main(String[] args) { Foobar vRet = CallByValueBugLibrary.INSTANCE.f1(); System.out.println(vRet.x); System.out.flush(); Foobar vCreated = new Foobar(); vCreated.x = 5; CallByValueBugLibrary.INSTANCE.f2(vCreated); CallByValueBugLibrary.INSTANCE.f2(vRet); } }
#include <stdio.h>
struct foobar { int x; };
struct foobar f1(void) { struct foobar r = { 42 }; return r; }
void f2(struct foobar *v) { if (v != (struct foobar*) 42) { printf("%p->x = %d\n", v, v->x); } else { printf("Called by value!!!\n"); } }







