Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Trabajar Con Bytes

Iniciado por [EX3], 06 de Octubre de 2004, 02:39:28 AM

« anterior - próximo »

[EX3]

 Wenas.

Resulta que estoy trabajando en un buffer de intercambio de datos para el TLSA Engine. El buffer es un array de tipo Byte en el que necesito guardar y leer valores de diferentes tipos: cadenas de texto (String), enteros largos (Long / DWORD) y coma flotante (Single / Float). De momento solo tengo implementada la lectura y escritura del mas sencillo de todos, las cadenas de texto y me quede bloqueado con el entero largo. Iluso de mi creia que sumando simplemente los 4 bytes que componen un Entero Largo obtendria el valor, pero ya averigue ke no es asi  (nooo)

Lo que busco en informacion de como leer y escribir Enteros Largos y decimales de Coma Flotante en array de Bytes. Gracias.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

averbell

 no entiendo muy bien a lo que te refieres, pero si lo que te pasa es que en lugar de crearte el numero 5900 te suma las cifras?

sés

 No sé si te he entendido, pero si tienes los números 1, 2, 3 y 4 y quieres formar el 1234... con 1+2+3+4 como que no lo consigues O_O

Para una entero sería algo como:
byte b[] = {0x04, 0x03, 0x02, 0x01 }
int i = b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);

Después de esto:
i = 0x01020304;

En el caso de C, lo más sencillo sería algo del tipo:
int i = *((int *)&b[n])

Para un float ahora mismo no lo sé, además depende mucho de cómo estén esos números en el array de bytes. En el ejemplo anterior el mismo nº podría estar almacenado como { 0x01, 0x02, 0x03, 0x04 }, lo que cambiaría la forma de crear el entero.

De todas formas... no entiendo bien el problema. Si tú mismo lees y escribes en ese buffer, pues hazlo como mejor te venga, ¿no?
Soy indeciso... ¿o no?

[EX3]

 A ver, me explico un poco mas:

Mediante la instruccion Put de VB guardo un valor de tipo Long (4 Bytes) en un archivo con acceso binario, por ejemplo.

Luego abro el archivo en modo binario y lo almaceno en un array de Bytes.

El valor de la variable que guarde era 40961024 que en hexadecimal seria: 0x00, 0x04, 0x71, 0x02, en binario seria: 0, 4, 113, 2.

La pregunta es, como hago yo para obtener el valor [40961024] de [0x00, 0x04, 0x71, 0x02] o [0, 4, 113, 2]?

Espero ke haya quedado algo mas claro  ;)

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

sés

Cita de: "[EX3"] Mediante la instruccion Put de VB guardo un valor de tipo Long (4 Bytes) en un archivo con acceso binario, por ejemplo.
Pues digo yo que habrá una función Get, ¿no?
Vamos, en los lenguajes que conozco, si tienes un putX(), en alguna parte existe un getX().

En el caso de que no existiera o de que no te sirviera por alguna extraña razón, pues implementa tú mismo los put y el get que necesites.
Soy indeciso... ¿o no?

[EX3]

 
Cita de: "sés"Pues digo yo que habrá una función Get, ¿no?
Vamos, en los lenguajes que conozco, si tienes un putX(), en alguna parte existe un getX().

En el caso de que no existiera o de que no te sirviera por alguna extraña razón, pues implementa tú mismo los put y el get que necesites.
A ver, lo de escribir a un archivo con Put era un ejemplo. Yo lo ke busco es poder tener un array de bytes en el ke poder escribir y leer un Long y un Single(Float), osea, interpretar los 4 bytes y componer el valor y viceversa segun tipo de dato mediante unas funciones propias como por ejemplo:
Sub Write_Long(Var As Long, Pos As Long) 'Escribe un valor Long en el array de Bytes.
Sub Read_Long(Var As Long, Pos As Long) 'Lee un valor Long del array de Bytes.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

sés

 Pues entonces usa el ejemplo que te puse al principio, que sería el get y haz el contrario para el put.
Soy indeciso... ¿o no?

averbell

 yo en mis programas uso el array
dim sdatos() as byte

'cargo los datos en la variable sdatos() con redim....

'''''''''''''''
Creo el buffer en sdatos.
cargo los datos en la varaiable con get #1,,sdatos

Para convertirlo
uso la funcion chr(sdatos(posicionbyte))

es decir
sdato(100)
sdato(29)
sdato(22)
sdato(22)
en asc e valor es (EJEMPLO)
100=3
29=4
22=1

3411
une los datos en una cadena string mediande & i luego combiertelo a un valor integer
si eso te paso mi ejemplo de como la hago yo


----------------------------------------
Ma software
Portal de informática y programación
y Soporte técnico.
Last Program: Virus and trojan Remover
Contact:Beltran_a@terra.es
----------------------------------------


Helius

 No te he entendido muy bien, pero si lo que quieres es serializar datos de 32 bits en una array de bytes prueba esto.

Yo no tengo ni idea de VB pero hice estas funciones en ensamblador que funcionan bien para hacer precisamente eso (supongo que podrás hacer lo mismo en VB dando algun rodeo):


//-------------------------------------------------------------------------------
// Función: UTIL_32toChar
// Propósito: Pasa el dato a 4 bytes, necesita un buffer de almenos 4 bytes
//-------------------------------------------------------------------------------
inline void UTIL_32toChar(int iData, byte* buffer)
{
Assert(buffer, "Se ha pasado un puntero inválido: UTIL_32toChar");

byte temp[4]={0};
byte* dir=temp;

__asm{
 push esi
 push eax
 mov esi, dir
 mov eax, iData
 mov [esi],al
 shr eax,8
 mov [esi+1],al
 shr eax,8
 mov [esi+2],al
 shr eax,8
 mov [esi+3],al
 pop eax
 pop esi
};

memcpy(buffer, temp, 4);
}

//-------------------------------------------------------------------------------
// Función: UTIL_CharTo32
// Propósito: Devuelve un dato de 4 bytes almacenado en un buffer (de almenos 4 bytes)
//-------------------------------------------------------------------------------
inline int UTIL_CharTo32int(byte* buffer)
{
Assert(buffer, "Se ha pasado un puntero inválido: UTIL_CharTo32");

byte temp[4]={0};
memcpy(temp, buffer, 4);
byte* dir=temp;

int result=0;

__asm{
 push esi
 push eax
 mov esi, dir
 mov al,[esi+3]
 shl eax,8
 mov al,[esi+2]
 shl eax,8
 mov al,[esi+1]
 shl eax,8
 mov al,[esi]
 mov result,eax
 pop eax
 pop esi
};

return result;
}


No se si tendrán sentido para ti, pero para mi si. Esas funciones estan hechas para ints pero valen para cualquier dato de 4 bytes.

Suerte.
Geardome Devlog
Tutoriales sobre DirectX 9, Nintendo DS y PSP.

[EX3]

 averbell, si no he entendido mal:
A = Chr(Byte(0)) & Chr(Byte(1)) & Chr(Byte(2)) & Chr(3))
A = Chr(0) & Chr(4) & Chr(113) & Chr(2)
A = "041132"

Que todo esto seria lo mismo que:
A = Byte(0) & Byte(1) & Byte(2) & Byte(3)
A = 0 & 4 & 113 & 2
A = 41132

41132 <> 40961024

Asi tampoco funciona. No se trata de una simple concatenacion de valores, algo mas hay ke hacer pero no tengo ni pajolera idea y llevo asi una semana intentando buscar la solucion via Google y con ayuda de un amigo que esta en la carrera y nada aun  :(

sés, tampoco me funciona bien con tu ejemplo.

Helius, gracias por el codigo, voy a intentar traducirlo al VB a ver si tira  :)

Si no llego a encontrar la solucion estoy pensando en hacer dos cosas:
1.- Cerrar el buffer a uso exclusivo del script, vamos, sin acceso desde archivos, asi podria hacerme mi propio formato para almacenar los numeros mas o menos de la manera ke mas descrito antes, agrupar el valor en numeros de 3 digitos en cada byte: 40961024 = ["000"|"040"|"961"|"024"] mas o menos.

2.- Crear el buffer en un archivo y acceder a el mediante Put y Get de VB, aunque esta opcion no me agrada mucho.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

[EX3]

 Por cierto, algun buen manual de ASM, por ke si no me va a ser imposible traducir tu codigo Helius  (yo de ASM 0 patartero (uoh) )
La verdad, con que me puedieras explicar ke hacen las funciones de tu codigo me bastaria supongo:
push esi
push eax
mov esi, <variable temporal>
mov eax, <variable integer>
mov [esi],al
shr eax,8
mov [esi+1],al
shr eax,8
mov [esi+2],al
shr eax,8
mov [esi+3],al
pop eax
pop esi

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

Helius

 Si, muy sencillo...

En esi tiene el puntero a la temporal.
En eax guarda el dato.

Mueve al primer byte de la temporal el byte mas bajo de eax.
Rota eax a la dercha 8 bits (con lo cual queda en la parte baja de eax el segundo byte de la temporal).

Mueve al segundo byte de la temporal (esi+1) el byte mas bajo de eax, que como lo habíamos rotado ahora será el segudo byte del dato.
Rota eax a la derecha 8 bits (con lo cual queda en la parte baja de eax el tercer byte de la temporal).

.
.
.

Así con los cuatro bytes que finalmente quedan en la temporal.

Luego copia esos cuatro bytes al búfer en donde los queríamos.
Geardome Devlog
Tutoriales sobre DirectX 9, Nintendo DS y PSP.

Helius

 Un ejemplo:

Si el número es 0x02578945 crearía en el array temporal de 4 bytes lo siguiente:

45 89 57 02

Logicamente para recuperar los cuatro bytes se hace lo contrario ;)

Espero que lo hallas entendido, en VB se podrá hacer de alguna manera, en vez de rotar divide, es lo mismo.
Geardome Devlog
Tutoriales sobre DirectX 9, Nintendo DS y PSP.

averbell

 Aquí te pongo ejemplo de un codigo echo:
tenenmos un fichero.dat que contiene la cadena 15.220
Dim memory() As Byte
Dim buffer As Integer
Dim variable As Single
Dim temporal As String
'///////////////////////////////////////
'/Cargar los datos en memoria/
'///////////////////////////////////////

Open "fichero.dat" For Binary As #1
buffer = LOF(1)
ReDim memory(0 To buffer) As Byte
Get #1, , memory
Close #1

'Crearemos una cadena con coma flotante que contiene 15,220
temporal = ""
For d = 0 To UBound(memory)
temporal = temporal & Chr(memory(d))
Next
variable = CSng(temporal)
msgbox  variable

'COMPROBADO variable sera igual a 15.220

sés

 Esto funciona perfectamente:
void putInt( int value, unsigned char buffer[], int pos )
{
  buffer[pos] = (unsigned char)(value & 0xff);
  buffer[pos+1] = (unsigned char)((value >> 8) & 0xff);
  buffer[pos+2] = (unsigned char)((value >> 16) & 0xff);
  buffer[pos+3] = (unsigned char)((value >> 24) & 0xff);
}


int getInt( unsigned char buffer[], int pos )
{
  int value;

  value = buffer[pos];
  value |= buffer[pos+1] << 8;
  value |= buffer[pos+2] << 16;
  value |= buffer[pos+3] << 24;

  return value;
}



NOTA: He puesto código de más para que se entienda mejor.
Soy indeciso... ¿o no?






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.