É interessante criar as seguintes três funções em Java:
public int htoni (int x) { // 4 bytes: C++ = "int" ou "long"
return ((x >> 24) & (0xFF) | (x >> 8) & (0xFF00) | (x << 8) & (0xFF0000) | (x << 24) & (0xFF000000));
}
public short htons (short x) { // 2 bytes: C++ = "short" ou "wchar_t"
return ...;
}
public long htonl (long x) { // 8 bytes: C++ = "long long" ou "__int64"
return ...;
}
Elas "invertem a ordem dos bytes" e são necessárias quando o programa em C++ está rodando em uma plataforma Intel ou AMD e o cara que codificou o programa não se importou com a ordem dos bytes.
Agora, quanto ao array de caracteres, gostaria de saber como é que o programa em C está esperando os dados. Ele espera que os caracteres sejam terminados por um "\0" ou então que haja um indicador de comprimento dos dados?
Se for o primeiro caso, deve ser algo como:
String s = "Gisele da Conceição Zózima Bündchen\0";
byte[] bytes = s.getBytes ("ISO-8859-1");
Se for o segundo, é uma coisa parecida com o primeiro, mas você tem de ver como é que o tal indicador deve ser gravado.
Dê uma olhada na classe ByteBuffer e FileChannel. Você daí não precisa fazer muita álgebra booleana, pode escolher se a ordem vai ser big ou little endian, etc.
Também tivemos que lidar com C++ aqui. A classe ByteBufferWorker em anexo vai te ajudar. Ela possui métodos para leitura de dados unsigned e também para leitura de strings terminadas em /0. Tem também uma função útil para gerar um dump de um ByteBuffer.
O meu problema é que tenho q gravar a seguinte estrutura para ser lida em C++:
typedef struct
{
char Nome[52]; // nome do usuario
WORD Classe; // classe do usuario
float ValCH; // valor de um CH
DWORD Num; // número de sequencia do usuario
}StructReg;
Criei uma classe chamada StructReg para se comportar como a struct e agora preciso gravar os dados num arquivo para ser lido uma unica vez como um bloco (a struct em si). e por isso preciso das conversões…
/* C++ - estou supondo que você esteja usando #pragma pack(1). Se não estiver usando #pragma pack(1), é necessário preencher com bytes zero cada campo para que ele comece em um endereço múltiplo de 4 */
typedef struct
{
char Nome[52]; // nome do usuario
WORD Classe; // classe do usuario
float ValCH; // valor de um CH
DWORD Num; // número de sequencia do usuario
}StructReg;
/* Java */
class Util {
public byte[] htons (short s) {
byte[] ret = new byte[2];
ret[0] = (byte) s;
ret[1] = (byte) (s>>8);
return ret;
}
public byte[] htoni (int x) {
byte[] ret = new byte[4];
ret[0] = (byte) s;
ret[1] = (byte) (s >> 8);
ret[2] = (byte) (s >> 16);
ret[3] = (byte) (s >> 24);
return ret;
}
}
class StructReg {
public String nome; /* 0..51 */
public short classe; /* 52...53 */
public float valch; /* 54...57 */
public int num; /* 58...61 */
/* Converte um StructReg em um array de bytes */
public byte[] getBytes() throws {
byte[] retorno = new byte[62];
byte[] bytesNome = nome.getBytes("ISO-8859-1");
byte[] bytesClasse = htons (classe);
byte[] bytesValch = htoni (Float.floatToIntBits (valch));
byte[] bytesNum = htoni (num);
int pos = 0;
System.arraycopy (bytesNome, 0, retorno, pos, bytesNome.length);
pos += bytesNome.length;
System.arraycopy (bytesClasse, 0, retorno, pos, bytesClasse.length);
pos += bytesClasse.length;
System.arraycopy (bytesValch, 0, retorno, pos, bytesValch.length);
pos += bytesValch.length;
System.arraycopy (bytesNum, 0, retorno, pos, bytesNum.length);
pos += bytesNum.length;
return retorno;
}
}