JNA 使用 Unix Stat 导致 UnsatisfiedLinkException
JNA causes UnsatisfiedLinkException with Unix Stat
所以,我正在尝试调用 Linux C - stat 函数。
我的 JNA 代码:
public int stat(bap path, bap statdump);
bap class:
public static class bap extends Structure {
public byte[] array;
public bap(int size) {
array = new byte[size];
}
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"array"});
}
}
虽然很讨厌,但它作为字节数组指针成功地用于许多其他函数。
我认为问题出在这里:int stat(const char *restrict path, struct stat *restrict buf);
,由 http://linux.die.net/man/3/stat
定义
如何传递常量字符数组,*restrict 是什么意思?我尝试 google,但我认为它不喜欢搜索查询中的 *,因为没有任何相关内容。
编辑:完全例外
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.UnsatisfiedLinkError: Error looking up function 'stat': java: undefined symbol: stat
at com.sun.jna.Function.<init>(Function.java:208)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:536)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:513)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:499)
at com.sun.jna.Library$Handler.invoke(Library.java:199)
at com.sun.proxy.$Proxy0.stat(Unknown Source)
您是否看过 sys/stat.h
以查看是否存在 stat()
的实际声明或者它是否是 C 预处理器宏?
在上面的link中,如果定义了__USE_FILE_OFFSET64
,stat
实际上将是stat64
。
要查看这是否是您的问题,只需将函数名称从 stat
更改为 stat64
。
作为更永久的解决方案,请为您的库加载提供 function mapper。
以下示例首先查找基本标签,然后在附加“64”后重试:
FunctionMapper mapper = new FunctionMapper() {
public String getFunctionName(NativeLibrary library, java.lang.reflect.Method method) {
String name = method.getName();
try {
library.getFunction(name);
} catch(UnsatisfiedLinkError e) {
try {
library.getFunction(name + "64");
return name + "64";
} catch(UnsatisfiedLinkError e) {
// If neither variant worked, report failure on the base label
}
}
return name;
}
};
Map options = new HashMap() {
{ put(Library.OPTION_FUNCTION_MAPPER, mapper); }
};
library = Native.loadLibrary("c", options);
所以,我正在尝试调用 Linux C - stat 函数。
我的 JNA 代码:
public int stat(bap path, bap statdump);
bap class:
public static class bap extends Structure {
public byte[] array;
public bap(int size) {
array = new byte[size];
}
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"array"});
}
}
虽然很讨厌,但它作为字节数组指针成功地用于许多其他函数。
我认为问题出在这里:int stat(const char *restrict path, struct stat *restrict buf);
,由 http://linux.die.net/man/3/stat
如何传递常量字符数组,*restrict 是什么意思?我尝试 google,但我认为它不喜欢搜索查询中的 *,因为没有任何相关内容。
编辑:完全例外
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.UnsatisfiedLinkError: Error looking up function 'stat': java: undefined symbol: stat
at com.sun.jna.Function.<init>(Function.java:208)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:536)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:513)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:499)
at com.sun.jna.Library$Handler.invoke(Library.java:199)
at com.sun.proxy.$Proxy0.stat(Unknown Source)
您是否看过 sys/stat.h
以查看是否存在 stat()
的实际声明或者它是否是 C 预处理器宏?
在上面的link中,如果定义了__USE_FILE_OFFSET64
,stat
实际上将是stat64
。
要查看这是否是您的问题,只需将函数名称从 stat
更改为 stat64
。
作为更永久的解决方案,请为您的库加载提供 function mapper。
以下示例首先查找基本标签,然后在附加“64”后重试:
FunctionMapper mapper = new FunctionMapper() {
public String getFunctionName(NativeLibrary library, java.lang.reflect.Method method) {
String name = method.getName();
try {
library.getFunction(name);
} catch(UnsatisfiedLinkError e) {
try {
library.getFunction(name + "64");
return name + "64";
} catch(UnsatisfiedLinkError e) {
// If neither variant worked, report failure on the base label
}
}
return name;
}
};
Map options = new HashMap() {
{ put(Library.OPTION_FUNCTION_MAPPER, mapper); }
};
library = Native.loadLibrary("c", options);