[英]JNA Structure inside a structure
I am quite new to JNA programming. 我对JNA编程很陌生。 I have a native code as below
我有如下的本机代码
int Data(int Number, aaa *Data, int* error);
typedef struct {
uint8 Storage;
LStr path;
int32 chart;
int32 strt;
LStr val;
int32 timedata;
} aaa;
typedef struct {
int32 cnt; /*num of bytes that follow*/
uChar str[1];
} LStrval, *LStrPtr, **LStr;
How can I call this native function from Java using JNA. 如何使用JNA从Java调用此本机函数。 I tried several options, but I am not getting the results.
我尝试了几种选择,但没有得到结果。 one of the options I tried is below.
我尝试的选项之一如下。
the interface function 接口功能
public int SetStorage_Data(int num,Storage_Data.ByReference data, Pointer error);
public class Storage_Data extends Structure{
public static class ByReference extends Storage_Data implements Structure.ByReference {}
public byte storage;
public Stringtype.ByReference savepath;
public int chart;
public int strt;
public Stringtype.ByReference val;
public int timedata;
@Override
protected List getFieldOrder() {
return Arrays.asList("storage", "savepath","chart",
"strt","val","timedata");
}
}
public class Stringtype extends Structure{
public static class ByReference extends Stringtype implements Structure.ByReference {
public ByReference(int buffersize) {
super(buffersize);
// TODO Auto-generated constructor stub
}}
public int count;
public byte[] str;
public Stringtype(int buffersize) {
str = new byte[buffersize];
count = str.length;
allocateMemory();
}
@Override
protected List getFieldOrder() {
return Arrays.asList("count", "str");
}
}
And the Java call 和Java调用
InjectionAnalyzerInterfaces.Storage_Data.ByReference storagedata = new InjectionAnalyzerInterfaces.Storage_Data.ByReference();
int len= string.length;
InjectionAnalyzerInterfaces.Stringtype.ByReference savepath = new InjectionAnalyzerInterfaces.Stringtype.ByReference(len);
byte[] stringbyte = string.getBytes();
System.arraycopy(stringbyte, 0, savepath.str, 0, bytes);
storagedata.savepath = savepath;
storagedata.chart = 1;
storagedata.strt =1;
String temp= "all";
byte[] strtbyte = temp.getBytes();
int dd = strtbyte.length;
InjectionAnalyzerInterfaces.Stringtype.ByReference stra = new InjectionAnalyzerInterfaces.Stringtype.ByReference(dd);
System.arraycopy(strtbyte, 0, stra.str,0, dd);
storagedata.strt = stra;
storagedata.tdata = 0;
Pointer error = new Memory(5);
int status1 = lib.Set_Config_Storage_Data(deviceNumber, storagedata, error);
Please do help me. 请帮帮我。 Thank you in advance
先感谢您
In defining your LStrVal
, you need to initialize the primitive array field so that JNA knows how much memory to allocate (at least to start with): 在定义
LStrVal
,您需要初始化原始数组字段,以便JNA知道要分配多少内存(至少LStrVal
开始):
public byte str = new byte[1];
You need to override Structure.read()
to do the right thing, and provide a Pointer
-based constructor to read after initializing from native memory: 您需要重写
Structure.read()
来做正确的事情,并提供一个基于Pointer
的构造函数,以便从本机内存初始化后进行读取:
public void read() {
count = (int)readField("count");
str = new byte[count];
super.read();
}
public LStr(Pointer p) {
super(p);
read();
}
Finally, your containing struct has struct**
fields (no idea why), which you'll have to map to Pointer
, and provide a convenience function to actually convert to your desired structure: 最后,您的包含结构具有
struct**
字段(不知道为什么),您必须将其映射到Pointer
,并提供便捷功能以实际转换为所需的结构:
public Pointer savepath;
public LStr getSavepath() {
return savepath != null ? new LStr(savepath.getPointer(0)) : null;
}
You're on the right track. 您走在正确的轨道上。
You need to declare the inner structure ( LStrVal
) as its own structure class. 您需要将内部结构(
LStrVal
)声明为其自己的结构类。 It looks like you've done that with your Stringtype
structure but you need to change a few things there: 看起来您已经用
Stringtype
结构完成了此操作,但是您需要在其中进行一些更改:
byte[]
array as 1, just use that constant. byte[]
数组的大小指定为1,只需使用该常数即可。 super()
super()
的无参数构造函数 super(p)
super(p)
ByReference
parts ByReference
部分 Then the outer structure you should use a PointerByReference
type for those structure pointers, and then in your main code, use new Stringtype(pbr.getValue())
to convert the pointer into the necessary class. 然后,外部结构应该为这些结构指针使用
PointerByReference
类型,然后在主代码中使用new Stringtype(pbr.getValue())
将指针转换为必要的类。
Alternately, as @technomage suggests, you could use a Pointer type, and then instead of getValue()
you'd use getPointer(0)
. 或者,正如@technomage所建议的,您可以使用Pointer类型,然后使用
getPointer(0)
代替getValue()
getPointer(0)
。 Bottom line is that you need a pointer (to a pointer) as your instance variable. 最重要的是,您需要一个指针(指向一个指针)作为实例变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.