简体   繁体   English

Java JNA链表声明

[英]Java JNA Linkedlist declaration

I need to access native C++ code.dll from Java application.我需要从 Java 应用程序访问本机 C++ 代码。dll。 native int function works well, but for Linkedlist Struct I cannot find any reference on the Internet how to declare the java interface native int function 效果很好,但是对于 Linkedlist Struct 我在互联网上找不到任何参考如何声明 java 接口

this C++ code此 C++ 代码

struct usb_relay_device_info
{
    unsigned char *serial_number;
    char *device_path;
    usb_relay_device_type type;
    usb_relay_device_info* next;
};

int EXPORT_API usb_relay_init(void);
struct usb_relay_device_info EXPORT_API * usb_relay_device_enumerate(void);
int EXPORT_API  usb_relay_device_open(struct usb_relay_device_info* device_info);

This is the java part这是 java 零件

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

public static class usb_relay_device_info extends Structure {
    public static class DeviceInfo extends usb_relay_device_info implements Structure.ByValue {
    }

    public byte[] serial_number = new byte[1024];
    public String device_path;
    public int type;
}


int usb_relay_init();
usb_relay_device_info.DeviceInfo usb_relay_device_enumerate();
int usb_relay_device_open(usb_relay_device_info.DeviceInfo deviceInfo);

} }

I already created just the struct at the java code (NOT the Linkedlist Struct).我已经在 java 代码(不是 Linkedlist 结构)中创建了结构。 So when I call the function the values are not showing up because it supposed to be a list (linkedlist in C++)因此,当我调用 function 时,值没有显示出来,因为它应该是一个列表(C++ 中的链表)

You say "I cannot find any reference on the Internet how to declare the java interface" but there are plenty of references, including JNA's Overview , linked to the main project page.您说“我在互联网上找不到任何关于如何声明 java 接口的参考资料”,但是有很多参考资料,包括 JNA 的概述,链接到主项目页面。

There you will find that char * is a C String and should be mapped to Java's String .在那里你会发现char *是一个 C String 并且应该映射到 Java 的String

The usb_relay_device_type mapping has to be referenced in the API that you're mapping. usb_relay_device_type映射必须在您正在映射的 API 中引用。 In this case it is an enum type, which is an integer, so int is probably appropriate here.在这种情况下,它是一个enum类型,即 integer,因此这里可能适合使用int (There are cases where it can be a smaller integer value like short or byte but those are rare.) (在某些情况下,它可以是较小的 integer 值,例如shortbyte ,但这种情况很少见。)

As for the pointer to the next device, that is also referenced on the overview page under struct* .至于指向下一个设备的指针,在struct*下的概述页面上也有引用。 The link (or explicitly) links to Structure.ByReference .链接(或显式)链接到Structure.ByReference That may not be obvious, but the JNA FAQ , also linked on the main JNA project page, amplifies.这可能不是很明显,但是JNA 常见问题解答(也链接在 JNA 项目主页面上)可以放大。 If it's still not clear, here's a summary:如果还不清楚,这里有一个总结:

  • By default, Structures listed as fields inside a Structure are treated "By Value", that is, the full structure and its fields are inserted in line.默认情况下,作为结构内字段列出的结构被视为“按值”,即完整结构及其字段插入行中。 To get this behavior you can simply declare the structure name.要获得这种行为,您可以简单地声明结构名称。
  • If you want the opposite behavior (By Reference) then you must explicitly state that, and JNA will map a pointer to the structure elsewhere.如果您想要相反的行为(通过引用),那么您必须明确 state ,并且 JNA 将 map 指向其他地方的结构的指针。 This is the case you have, and the correct structure mapping is usb_relay_device_info.ByReference .您就是这种情况,正确的结构映射是usb_relay_device_info.ByReference (You'll also need to change the structure declaration to implement ByReference -- the JNA overview, linked above, has an example of this.) (您还需要更改结构声明以实现 ByReference - 上面链接的 JNA 概述有一个示例。)
  • When used in function arguments, such as usb_relay_device_open() , the opposite is true: the "By Reference" is the default, and you only need to explicity specify "By Value" if that's relevant.在 function arguments 中使用时,例如usb_relay_device_open() ,则相反:“By Reference”是默认值,如果相关,您只需明确指定“By Value”。 In this case, it's not -- the native declaration includes the pointer: ( usb_relay_device_info* ) so you want the ByReference behavior.在这种情况下,它不是 - 本机声明包含指针:( usb_relay_device_info* )所以您需要 ByReference 行为。 You can just put usb_relay_device_info device_info there and the ByReference will be implicit.您可以将usb_relay_device_info device_info放在那里,ByReference 将是隐式的。 Or, if you prefer (it's not needed) you could do usb_relay_device_info.ByReference device_info and it would just be redundant.或者,如果您愿意(不需要),您可以执行usb_relay_device_info.ByReference device_info ,这只是多余的。

So in summary your structure mapping should be:因此,总而言之,您的结构映射应该是:

class usb_relay_device_info extends Structure {
    public static class ByReference extends usb_relay_device_info implements Structure.ByReference { }

    public String serial_number;
    public String device_path;
    public int type;
    public usb_relay_device_info.ByReference next;
};

You'll need to add the FieldOrder, preferably using an annotation.您需要添加 FieldOrder,最好使用注释。

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

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