在 Java 中使用 C 结构

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1287903/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 15:57:56  来源:igfitidea点击:

Using C struct in Java

javac

提问by Rohin

I have to code a Java program that will receive messages from network and display their content to the user. The problem is that the messages that I receive are simply binary dumps of C structures. Add to this some of the messages are coming from little endian machines and some from big endian without the fields being converted to network byte order. One way I have is to use JNI and convert c structs to some XML string and then de serialize this XML string to a Java Object. This is a laborous job since there about 122 different structs and each one of them contains more than 20 fields. I wonder if there is a library/tool/methodology which could make my job a bit easy ?

我必须编写一个 Java 程序,该程序将从网络接收消息并将其内容显示给用户。问题是我收到的消息只是 C 结构的二进制转储。除此之外,一些消息来自小端机器,一些来自大端机器,而没有将字段转换为网络字节顺序。我的一种方法是使用 JNI 并将 c 结构转换为一些 XML 字符串,然后将此 XML 字符串反序列化为 Java 对象。这是一项艰巨的工作,因为大约有 122 个不同的结构,每个结构都包含 20 多个字段。我想知道是否有一个图书馆/工具/方法可以让我的工作变得轻松一点?

采纳答案by Brian Agnew

Swigwill handle a lot of the tedious repetitive work for you in terms of mapping the C structs to Java objects. Check out the Swig/Java manualand the entry on wrapping C structures.

在将 C 结构映射到 Java 对象方面,Swig将为您处理许多繁琐的重复工作。查看Swig/Java 手册和有关包装 C 结构的条目。

回答by Trevor Harrison

There is a library called Preon that was designed to help you with this type of task: Preon siteBasically, they try to keep all the logic for reading your pojo's from the binary stream in annotations tied to each field in your pojo.

有一个名为 Preon 的库旨在帮助您完成此类任务:Preon 站点基本上,他们尝试将所有逻辑用于从二进制流中读取 pojo 的注释与您的 pojo 中的每个字段相关联。

An example from their docs where you control the size of the int you are reading:

他们的文档中的一个示例,您可以在其中控制正在阅读的 int 的大小:

class Rectangle
{
  @BoundNumber(size="16") private int x1;
  @BoundNumber(size="16") private int y1;
  @BoundNumber(size="16") private int x2;
  @BoundNumber(size="16") private int y2;
}

or to specify endianness:

或指定字节序:

class Rectangle
{
  @BoundNumber(byteOrder=LittleEndian) private int x1;
  @BoundNumber(byteOrder=LittleEndian) private int y1;
  @BoundNumber(byteOrder=LittleEndian) private int x2;  
  @BoundNumber(byteOrder=LittleEndian) private int y2;
}

You can even use mini-equations with references to values in previous fields to specify size / length, etc.

您甚至可以使用引用先前字段中的值的迷你方程来指定大小/长度等。

@BoundList(size="width * height") byte[] pixels;
@BoundNumber(size="nrBits * 2") int value;

Oh, and they also offer conditional logic, all in annotations.

哦,他们还提供条件逻辑,全部在注释中。

回答by Joachim Sauer

You can use DataInputStreamto load data from any InputStream. As long as you know the exact layout of your structs, this should be sufficient.

您可以使用DataInputStream从任何InputStream. 只要您知道结构的确切布局,这就足够了。

回答by dfa

There are several libraries that help in this area. One of the simplest to use (annotation driver) is certainly Preon

有几个图书馆可以在这方面提供帮助。最简单的使用(注解驱动)之一当然是Preon

回答by Ken

java.nio has ByteBuffer, which supports flipping byte order when reading and writing, on-the-fly if necessary.

java.nio 有 ByteBuffer,它支持在读写时翻转字节顺序,必要时即时翻转。