JNR-FFI
类型转换
基本类型
将 C 的类型和Java类型自动转换。
C Type | Java Type | Size |
---|---|---|
char |
byte |
8 bit integer |
short |
short |
16 bit integer |
int |
int |
32 bit integer |
long |
long |
natural long, 32 bits on 32 bit systems, 64 bits on 64 bit systems |
float |
float |
32 bit floating point |
double |
double |
64 bit floating point |
const char * |
String or Pointer |
|
void * |
Pointer or Buffer |
|
int * | IntByReference | 其他float*有类似的类 |
void ** | PointerByReference | |
C enum | Mostly int |
结构体/Union
c
Java
// Union类似,集成Union类即可
public class Timespec extends Struct {
// 结构体使用自己的基本类型
// Struct types can be found as inner classes of the Struct class
public Struct.SignedLong tv_sec = new Struct.SignedLong();
public Struct.SignedLong tv_nsec = new Struct.SignedLong();
// Necessary constructor that takes a Runtime
public Timespec(jnr.ffi.Runtime runtime) {
super(runtime);
}
// You can add your own methods of choice
public void setTime(long sec, long nsec) {
tv_sec.set(sec);
tv_nsec.set(nsec);
}
}
枚举
c 枚举定义:
enum fuse_buf_flags {
FUSE_BUF_IS_FD = (1 << 1),
FUSE_BUF_FD_SEEK = (1 << 2),
FUSE_BUF_FD_RETRY = (1 << 3),
};
Java对应定义(可以自动转换)
public enum FuseBufFlags implements EnumMapper.IntegerEnum {
FUSE_BUF_IS_FD(1 << 1),
FUSE_BUF_FD_SEEK(1 << 2),
FUSE_BUF_FD_RETRY(1 << 3);
private final int value;
FuseBufFlags(int value) {
this.value = value;
}
@Override
public int intValue() {
return value;
}
}
函数类型
Java对应调用的写法:
public interface ExampleLibrary {
public interface MyCallback { // type representing callback
@Delegate
int invoke(Pointer data); // function name doesn't matter, it just needs to be the only function and have @Delegate
}
int setCallback(MyCallback callback);
}
Function pointer is valid as long as the instance stays strongly-referenced.
ObjectReferenceManager referenceManager = Runtime.getRuntime(lib).newObjectReferenceManager();
MyCallback callback = data -> 0;
Pointer key = referenceManager.add(callback);
lib.setCallback(callback); // Callback is passed internally as a function pointer
referenceManager.remove(key); // Free the callback when no more required
内存管理
Pointers
native memory 地址的引用;
示例
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-ffi</artifactId>
<version>2.2.12</version>
</dependency>
示例代码:
import jnr.ffi.*;
import jnr.ffi.types.pid_t;
/**
* Gets the process ID of the current process, and that of its parent.
*/
public class Getpid {
public interface LibC {
// 跟libc.so的getpid的本地方法匹配
public @pid_t long getpid();
public @pid_t long getppid();
}
public static void main(String[] args) {
// load libc.so
LibC libc = LibraryLoader.create(LibC.class).load("c");
System.out.println("pid=" + libc.getpid() + " parent pid=" + libc.getppid());
}
}