leonbloy
leonbloy

Reputation: 75906

Passing a Structure with a Memory field in JNA

My dynamic C library receives some (pointer to) structures that include an allocated pointer (by malloc). The called function is allowed to call realloc on it.

typedef struct mystruct {
    void * buf;
    int buflen;
    /* more fields... */
} mystruct;


void myfunc(mystruct  *s1, /* more args*/) {  /* in dynamic library */
   /* .... */
      s1->buf = realloc(s1->buf,newsize);
   /* .... */
}

I thought that a Structure with a Memory field would do the trick,

public class MyStructJna extends Structure {
    public Memory buf;
    public Integer buflen;
            /* .... */
}

but then I get this Exception:

Exception in thread "main" java.lang.IllegalArgumentException: 
 Structure field "buf" was declared as class com.sun.jna.Memory, 
 which is not supported within a Structure
        at com.sun.jna.Structure.writeField(Structure.java:792)

Any explanation and/or workaround? I'm using JNA 4.0


The question was answered and accepted, but I want to add this caveat, in case someone is attempting a similar approach:

This is not a good design, because the DLL side will do a realloc of a pointer allocated in the JNA side, and, finally, the JNA side will attempt to free that pointer (allocated in the DLL side). This is in general not safe.

Upvotes: 0

Views: 968

Answers (1)

technomage
technomage

Reputation: 10069

You can't use Memory because it must be possible for JNA to automatically initialize all fields of the structure.

You can certainly give the field Pointer type and assign a Memory object to it. The field will generally be preserved as long as the native code does not modify its value.

Upvotes: 2

Related Questions