【发布时间】:2018-12-18 05:31:03
【问题描述】:
我正在尝试通过JNA 调用以下函数:
结构组 * getgrnam (const char *name)
如中所述: http://www.gnu.org/software/libc/manual/html_node/Lookup-Group.html#Lookup-Group
根据文档,结构如下:
char *gr_name
组的名称。
gid_t gr_gid
组的组 ID。
char **gr_mem
指向组中用户名称的指针向量。每个用户名都是一个以空字符结尾的字符串,向量本身以空指针结尾。
我创建了以下简单的测试类
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);
}
}
以及表示结构的 Group 类:
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;
}
}
marshalling documentation of JNA 声明 char** 被转换为 String[]。
但是,当我运行此代码时,出现以下错误:
/tmp # java -cp .:jna-4.5.1.jar 测试root Hello, World Exception in 线程“main”java.lang.IllegalArgumentException:读取数组 不支持内存中的类 java.lang.String 在 com.sun.jna.Pointer.readArray(Pointer.java:538) 在 com.sun.jna.Pointer.getValue(Pointer.java:459) 在 com.sun.jna.Structure.readField(Structure.java:720) 在 com.sun.jna.Structure.read(Structure.java:580) 在 com.sun.jna.Structure.autoRead(Structure.java:2074) 在 com.sun.jna.Structure.conditionalAutoRead(Structure.java:550) 在 com.sun.jna.Function.invoke(Function.java:446) 在 com.sun.jna.Function.invoke(Function.java:354) 在 com.sun.jna.Library$Handler.invoke(Library.java:244) 在 com.sun.proxy.$Proxy0.getgrnam(未知来源) 在 Test.main(Test.java:23)
char**的结构域如何正确转换?
【问题讨论】:
-
我找到的文档仅说明
group“应包括”这 3 个成员,而不是它将包含仅这些成员。因此,您可能必须在 C 中创建一个调用getgrnam并返回更明确定义的包装函数。 -
谢谢。我猜这也将是一个问题。查看 JNL 的源代码,它似乎根本没有实现将位于结构中的 char** 转换为对象中的 String[]。我尝试了 2-3 个解决方法,但到目前为止没有成功。将继续挖掘。
-
你能不能只得到一个
Pointers 的数组,然后在每个Pointer上使用getString()? -
@DanielWiddis 尝试过,它显示出一些进展。从某种意义上说,Pointer[] 填充了一些“数据”。不幸的是,尝试通过 getString() 甚至 getChar() 读取这些数据会导致 VM 崩溃。可能与第一个评论有关,即返回的结构可以包含比记录更多的字段。