I'm attempting to call following function via JNA:
struct group * getgrnam (const char *name)
as described in: http://www.gnu.org/software/libc/manual/html_node/Lookup-Group.html#Lookup-Group
According to the documentation the structure is following:
char *gr_name
The name of the group.
gid_t gr_gid
The group ID of the group.
char **gr_mem
A vector of pointers to the names of users in the group. Each user name is a null-terminated string, and the vector itself is terminated by a null pointer.
I created following simple test classes
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
public class Test {
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);
void printf(String format, Object... args);
public Group getgrnam(String groupName);
}
public static void main(String[] args) {
CLibrary.INSTANCE.printf("Hello, World\n");
Group group = CLibrary.INSTANCE.getgrnam(args[0]);
System.out.println(group.gr_name);
System.out.println(group.gr_mem);
}
}
and the Group class that represents the structure:
import java.util.ArrayList;
import java.util.List;
import com.sun.jna.Structure;
public class Group extends Structure {
public String gr_name;
public int gr_gid;
public String[] gr_mem = new String[128];
@Override
protected List<String> getFieldOrder() {
List<String> fields = new ArrayList<>();
fields.add("gr_name");
fields.add("gr_gid");
fields.add("gr_mem");
return fields;
}
}
The marshalling documentation of JNA states that char** is converted to String[].
However when I run this code I get following error:
/tmp # java -cp .:jna-4.5.1.jar Test root Hello, World Exception in thread "main" java.lang.IllegalArgumentException: Reading array of class java.lang.String from memory not supported at com.sun.jna.Pointer.readArray(Pointer.java:538) at com.sun.jna.Pointer.getValue(Pointer.java:459) at com.sun.jna.Structure.readField(Structure.java:720) at com.sun.jna.Structure.read(Structure.java:580) at com.sun.jna.Structure.autoRead(Structure.java:2074) at com.sun.jna.Structure.conditionalAutoRead(Structure.java:550) at com.sun.jna.Function.invoke(Function.java:446) at com.sun.jna.Function.invoke(Function.java:354) at com.sun.jna.Library$Handler.invoke(Library.java:244) at com.sun.proxy.$Proxy0.getgrnam(Unknown Source) at Test.main(Test.java:23)
How can the structure field of char** be properly converted?
group"shall include" those 3 members, not that it will contain only those members. So you may have to create a wrapper function in C that callsgetgrnamand returns something that is more well-defined. - MichaelPointers and then usegetString()on eachPointer? - Daniel Widdis