有什么有效的方法可以使用 JNA 读取动态大小的共享内存段吗?
Is there any effective way to read dynamic size shared memory segment using JNA?
我试图找到以结构数组形式(在 C 中)读取共享内存的有效方法:
typedef struct the_struct {
int id;
int data;
} the_c_struct;
static the_c_struct *the_struc_ptr = NULL;
目前我使用以下 JNA Structure
代码从共享内存中检索数据:
public class MyCStruc extends Structure {
public int id;
public int data;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"id", "data"});
}
@Override
public void useMemory(Pointer m, int offset) {
super.useMemory(m, offset);
super.read();
}
@Override
public void useMemory(Pointer m) {
super.useMemory(m);
super.read();
}
}
并使用 shmget
和 shmat
的本机实现读取共享内存:
memId = NativeLib.INSTANCE.shmget(0x999, memSize, 0);
CStructPtr = NativeLib.INSTANCE.shmat(memId, null, 0);
MyCStruc cs=new MyCStruc();
for (int i=0;i<CStructArraySize;i+=8) {
cs.useMemory(CStructPtr,i);
// to read a record of struct array
// do something with the data
}
上面的代码确实有效,但我想我可以做一些更有效的事情来读取结构数组?对吗?
注意: 结构数组的大小是动态的,但我可以设法获取共享内存的大小。
不要在这里使用 Structure
,只需让 shmat
调用 return 一个 Pointer
并使用 Pointer.getInt(0)
获取 ID 和Pointer.getInt(4)
获取 data
字段。
您甚至可以使用 Native.getDirectBufferPointer()
为您提供一个 NIO 缓冲区,您可以将其传递给其他 Java 代码。
如果您正在读取连续分配的数组 struct
,那么您应该使用基于 Pointer
的构造函数创建您的第一个 Structure
,然后调用 Structure.toArray(size)
在该实例上加载完整数组。
Pointer p = lib.shmat();
MyCStruc s = new MyCStruc(p);
MyCStruc[] array = (MyCStruc[])s.toArray(size);
构造函数:
public class MyCStruc extends Structure {
public MyCStruc(Pointer p) {
super(p);
read();
}
}
这是我的最终代码:
memId = NativeLib.INSTANCE.shmget(0x999, memSize, 0);
CStructPtr = NativeLib.INSTANCE.shmat(memId, null, 0);
CStructArraySize=memSize/8;
MyCStruc cs=new MyCStruc(CStructPtr);
MyCStruc[] acs=(MyCStruc[])cs.toArray(CStructArraySize);
int i=0;
while (i<CStructArraySize) {
System.out.printf("id=%d data=%d\n", acs[i].id, acs[i].data);
// do something else with the data
i++;
}
MyCStruc
现在:
public class MyCStruc extends Structure {
public int id;
public int data;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"id", "data"});
}
public MyCStruc(Pointer p) {
super(p);
read();
}
}
我试图找到以结构数组形式(在 C 中)读取共享内存的有效方法:
typedef struct the_struct {
int id;
int data;
} the_c_struct;
static the_c_struct *the_struc_ptr = NULL;
目前我使用以下 JNA Structure
代码从共享内存中检索数据:
public class MyCStruc extends Structure {
public int id;
public int data;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"id", "data"});
}
@Override
public void useMemory(Pointer m, int offset) {
super.useMemory(m, offset);
super.read();
}
@Override
public void useMemory(Pointer m) {
super.useMemory(m);
super.read();
}
}
并使用 shmget
和 shmat
的本机实现读取共享内存:
memId = NativeLib.INSTANCE.shmget(0x999, memSize, 0);
CStructPtr = NativeLib.INSTANCE.shmat(memId, null, 0);
MyCStruc cs=new MyCStruc();
for (int i=0;i<CStructArraySize;i+=8) {
cs.useMemory(CStructPtr,i);
// to read a record of struct array
// do something with the data
}
上面的代码确实有效,但我想我可以做一些更有效的事情来读取结构数组?对吗?
注意: 结构数组的大小是动态的,但我可以设法获取共享内存的大小。
不要在这里使用 Structure
,只需让 shmat
调用 return 一个 Pointer
并使用 Pointer.getInt(0)
获取 ID 和Pointer.getInt(4)
获取 data
字段。
您甚至可以使用 Native.getDirectBufferPointer()
为您提供一个 NIO 缓冲区,您可以将其传递给其他 Java 代码。
如果您正在读取连续分配的数组 struct
,那么您应该使用基于 Pointer
的构造函数创建您的第一个 Structure
,然后调用 Structure.toArray(size)
在该实例上加载完整数组。
Pointer p = lib.shmat();
MyCStruc s = new MyCStruc(p);
MyCStruc[] array = (MyCStruc[])s.toArray(size);
构造函数:
public class MyCStruc extends Structure {
public MyCStruc(Pointer p) {
super(p);
read();
}
}
这是我的最终代码:
memId = NativeLib.INSTANCE.shmget(0x999, memSize, 0);
CStructPtr = NativeLib.INSTANCE.shmat(memId, null, 0);
CStructArraySize=memSize/8;
MyCStruc cs=new MyCStruc(CStructPtr);
MyCStruc[] acs=(MyCStruc[])cs.toArray(CStructArraySize);
int i=0;
while (i<CStructArraySize) {
System.out.printf("id=%d data=%d\n", acs[i].id, acs[i].data);
// do something else with the data
i++;
}
MyCStruc
现在:
public class MyCStruc extends Structure {
public int id;
public int data;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"id", "data"});
}
public MyCStruc(Pointer p) {
super(p);
read();
}
}