简体   繁体   English

如何在JNA中传递包含原始类型数组的结构?

[英]How to pass a struct including a array of primitive type in JNA?

I'm a novice JNA developer so please forgive me if this question is trivial, but I'm struggling against dealing with C-lang struct object including an array of float with JNA. 我是JNA的新手开发人员,因此,如果这个问题很琐碎,请原谅我,但我努力避免使用CNA结构对象,包括JNA的float数组。 Currently I got a compile error. 目前,我收到了一个编译错误。

I think the problem is the wrong way to initialize and assign FloatByReference instance ( mys.Weights ) to mystruct class instance ( mys ), and believe that Java code below should not be modified because JNAerator automatically generated it. 我认为问题是初始化FloatByReference实例( mys.Weights )并将其分配给mystruct类实例( mys )的错误方法,并且认为不应修改以下Java代码,因为JNAerator自动生成了它。

My C Code: 我的C代码:

typedef struct
{
  int n;
  float *Weights;
} mystruct;

void testfunc(mystruct* mys){
  printf(mys->Weights[0]);
}

public interface CLibrary extends Library {
    public static final String JNA_LIBRARY_NAME = "test";
    public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(CLibrary.JNA_LIBRARY_NAME);
    public static final CLibrary INSTANCE = (CLibrary)Native.loadLibrary(CLibrary.JNA_LIBRARY_NAME, CLibrary.class);

and Java: 和Java:

public interface CLibrary extends Library {
    public static final String JNA_LIBRARY_NAME = "test";
    public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(CLibrary.JNA_LIBRARY_NAME);
    public static final CLibrary INSTANCE = (CLibrary)Native.loadLibrary(CLibrary.JNA_LIBRARY_NAME, CLibrary.class);


    public static class mystruct extends Structure {
        public int n;
        public FloatByReference Weights;
        protected List<? > getFieldOrder() {
            return Arrays.asList("n", "Weights");
        }
        public mystruct(int n, JnaeratorTestLibrary.feature_t.ByReference Features, FloatByReference Weights) {
            super();
            this.n = n;
            this.Features = Features;
            this.Weights = Weights;
        }
        public mystruct(Pointer peer) {
            super(peer);
        }
        public static class ByReference extends mystruct implements Structure.ByReference {

        };
        public static class ByValue extends mystruct implements Structure.ByValue {

        };
    };
    void testfunc(CLibrary.mystruct mys);
}

public static void main(String[] args) {
    mystruct mys = new mystruct();
    mys.n = 10;
    mys.Weights = new FloatByReference();
    // Compile error raises.
    mys.Weights = new float[4]; mys.Weights[0] = 1.0;

    testfunc(mys);
}

Compile Error message: 编译错误消息:

Type mismatch: cannot convert from float[] to FloatByReference 类型不匹配:无法从float []转换为FloatByReference

Use Pointer , then use Pointer.getFloatArray(0, n) to extract the data you want. 使用Pointer ,然后使用Pointer.getFloatArray(0, n)提取所需的数据。

You'll need to allocate Memory and use Memory.write() to write a Java primitive float array to native memory before assigning that memory to your structure field. 您需要分配Memory并使用Memory.write()将Java基本浮点数组写入本机内存,然后再将该内存分配给您的结构字段。

FloatByReference is basically a pointer to one allocated float. FloatByReference基本上是指向一个已分配浮点的指针。 JNAerator simply can't tell the difference between a pointer to a single float and a pointer to a buffer of floats (nor can a human without some additional context). JNAerator根本无法分辨出指向单个浮点数的指针与指向浮点数的缓冲区的指针之间的区别(如果没有其他上下文,人类也不会)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM