Utilisation de la structure C en Java

Je dois coder un programme Java qui va recevoir des messages du réseau et afficher leur contenu à l’utilisateur. Le problème est que les messages que je reçois sont simplement des images binarys de structures C. Ajoutez à cela certains messages provenant de machines little endian et d’autres de big endian sans que les champs soient convertis en ordre d’octets réseau. L’une des méthodes que j’ai est d’utiliser JNI et de convertir les structures c en une chaîne XML, puis de sérialiser cette chaîne XML en object Java. C’est un travail laborieux puisqu’il existe environ 122 structures différentes et chacune d’entre elles contient plus de 20 champs. Je me demande s’il existe une bibliothèque / un outil / une méthodologie qui pourrait rendre mon travail un peu facile?

Swig prendra en charge une grande partie du travail fastidieux et répétitif en termes de mappage des structures C vers des objects Java. Consultez le manuel Swig / Java et l’entrée sur l’ encapsulation de structures en C.

Il existe une bibliothèque appelée Preon qui a été conçue pour vous aider dans ce type de tâche: Site Preon Essentiellement, ils essaient de conserver toute la logique permettant de lire vos pojo du stream binary dans des annotations liées à chaque champ de votre pojo.

Un exemple de leur documentation où vous contrôlez la taille de l’int que vous lisez:

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; } 

ou pour spécifier 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; } 

Vous pouvez même utiliser des mini-équations avec des références aux valeurs des champs précédents pour spécifier la taille / longueur, etc.

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

Oh, et ils offrent également une logique conditionnelle, le tout dans des annotations.

Il existe plusieurs bibliothèques qui aident dans ce domaine. L’un des plus simples à utiliser (pilote d’annotation) est certainement Preon

Vous pouvez utiliser DataInputStream pour charger des données à partir de n’importe quel InputStream . Tant que vous connaissez la disposition exacte de vos structures, cela devrait être suffisant.

java.nio a ByteBuffer, qui prend en charge l’inversion de l’ordre des octets lors de la lecture et de l’écriture, à la volée si nécessaire.