我正在尝试从Mathlab生成的dll调用函数。它似乎在C中正常工作,但是当我尝试使用jna时它会返回奇怪的结果。
我正在尝试使用以下签名调用该函数:
emxArray_real32_T *emxCreate_real32_T(int rows, int cols);
结构:
struct emxArray_real32_T
{
float *data;
int *size;
int allocatedSize;
int numDimensions;
boolean_T canFreeData;
};
结构在java中映射到:
public interface LibSoftEdge extends StdCallLibrary {
public static class emxArray_real32_T extends Structure{
public Pointer data ;
public Pointer size;
public int numDimensions;
public int allocatedSize;
public boolean canFreeData;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"allocatedSize","canFreeData",
"data","numDimensions","size"});
}
@Override
public String toString() {
return "emxArray_real32_T{" +
"data=" + data +
", size=" + size +
", allocatedSize=" + allocatedSize +
", numDimensions=" + numDimensions +
", canFreeData=" + canFreeData +
'}';
}
}
emxArray_real32_T emxCreate_real32_T(int rows, int cols);
}
我称之为:
LibSoftEdge libM = (LibSoftEdge) Native.loadLibrary("libsoftedge", LibSoftEdge.class);
LibSoftEdge.emxArray_real32_T test;
test = libM.emxCreate_real32_T(3,3);
在测试对象中,我得到奇怪的值和空指针。
任何建议都是非常苛刻的。
答案 0 :(得分:2)
当您返回这样的字段顺序时:
@Override
protected List getFieldOrder() {
return Arrays.asList("allocatedSize","canFreeData", "data","numDimensions","size");
}
您告诉JNA您的原生struct
看起来像这样:
struct emxArray_real32_T
{
int allocatedSize; // actually 'data'
boolean_T canFreeData; // actually 'size'
float *data; // actually 'allocatedSize'
int numDimensions;
int *size; // actually 'canFreeData'
};
因此,当JNA填充Java端的字段时,您的值将不正确,因为您实际上是在扰乱您的字段。
此外,根据boolean_T
的大小,您可能也会阅读未对齐的数据,甚至可能最终崩溃。
您的getFieldOrder()
应如下所示:
@Override
protected List getFieldOrder() {
return Arrays.asList("data", "size", "allocatedSize", "numDimensions", "canFreeData");
}
最后,如果你想为boolean
使用Java boolean_T
而boolean_T
是除了四个字节以外的任何大小,那么你需要使用TypeMapper
来确保正确转换类型。