从C获取结构(按引用)

时间:2015-02-16 18:28:40

标签: java jna

假设我有下一个C代码片段,我想使用JNA从Java调用它。

typedef struct {
            int                     bit_a;
            int                     bit_b;
} * bit_handle;

bit_handler handle_open(const char *name, int prop);

出于这个目的,我编写了下一个Java代码片段:

Java代码:

 public interface BitLibrary extends Library {
        BitLibrary INSTANCE = (BitLibrary) Native.loadLibrary("bitlibrary", BitLibrary.class);
        Pointer handler_open(char* name, int prop);
    }

它完美地工作,但是我想通过引用检索BitHandle对象(参见下面的实现)而不是指针,因为前面的C代码中的bit_handle是一个指针。我怎么能这样做?我尝试过看起来像this example的东西但是我得到了一个ClassCastException,它说java.lang.reflect.Field不能转换为java.lang.Comparable而且我有点无能为力,因为从逻辑的角度来看应该有效,但它没有。我错过了什么吗?

BitHandle实现:

    public static class BitHandle extends Structure {
        public int bit_a;
        public int bit_b;

        public BitHandle(Pointer peer){
            super(peer);
        }

        @Override
        @SuppressWarnings({ "rawtypes", "unchecked" })
        protected List<?> getFieldOrder() {
            List fieldList = new ArrayList(super.getFieldList());
            fieldList.addAll(Arrays.asList("bit_a", "bit_b"));
            return fieldList;
        }

    }

1 个答案:

答案 0 :(得分:1)

找到解决方案,感谢@ user2864740建议。关键是忽略getFieldOrder()javadoc并按如下方式实现它:

public class BitTest {

    public interface BitLibrary extends Library {
        BitLibrary INSTANCE = (BitLibrary) Native.loadLibrary("bit", BitLibrary.class);

        public static class BitHandle extends Structure {
            public int bit_a;
            public int bit_b;
            public static class ByReference extends BitHandle implements Structure.ByReference {}


            @Override
            protected List getFieldOrder() {
                List<String> fieldList = new ArrayList<>();
                fieldList.addAll(Arrays.asList("bit_a", "bit_b"));
                return (List) fieldList;
            }

        }


        BitHandle.ByReference bit_open(String drivername, int lun);

    }

    public static void main(String[] args) {
        BitLibrary.BitHandle.ByReference pointer = BitLibrary.INSTANCE.Bit_open("CIBM_LINUX", 0);
   }

}