我试图找到以结构数组形式读取共享内存的有效方法(在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
}
上面的代码实际上是有效的,但我想我可以做一些更有效的方法来读取struct的数组?正确?
注意:struct数组的大小是动态的,但我可以设法获得共享内存的大小。
答案 0 :(得分:1)
请勿在此处使用Structure
,只需让shmat
来电回复Pointer
,然后使用Pointer.getInt(0)
获取ID,Pointer.getInt(4)
即可获取data
字段。
您甚至可以使用Native.getDirectBufferPointer()
为您提供一个可以传递给其他Java代码的NIO缓冲区。
如果您正在阅读连续分配的struct
数组,那么您应该使用基于Structure
的构造函数创建第一个Pointer
,然后在其上调用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();
}
}
答案 1 :(得分:0)
这是我的最终代码:
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();
}
}