El paso a paso o código que verás en este post es la resolución más sencilla y efectiva que hallamos a tus dudas o problema.
Solución:
Dada la necesidad de obtener los valores de uint8_t en uint32_t, y las especificaciones en in4_pton () …
Intente esto con una posible corrección en el orden de bytes:
uint32_t i32 = v4[0] | (v4[1] << 8) | (v4[2] << 16) | (v4[3] << 24);
Hay un problema con su ejemplo, en realidad con lo que está tratando de hacer (ya que no quiere los cambios).
Mira, es un hecho poco conocido, pero no está permitido cambiar los tipos de puntero de esta manera
específicamente, un código como este es ilegal:
type1 *vec1=...;
type2 *vec2=(type2*)vec1;
// do stuff with *vec2
El único caso en el que esto es legal es si type2
es char
(o unsigned char
o const char
etc.), pero si type2
es cualquier otro tipouint32_t
en su ejemplo) va en contra del estándar y puede introducir errores en su código si compila con -O2
o -O3
mejoramiento.
Esto se denomina "regla de alias estricto" y permite a los compiladores asumir que los punteros de diferentes tipos nunca apuntan a puntos relacionados en la memoria, de modo que si cambia la memoria de un puntero, el compilador no tiene que volver a cargar todos los demás. punteros.
Es difícil para los compiladores encontrar casos en los que se rompa esta regla, a menos que usted lo deje muy claro. Por ejemplo, si cambia su código para hacer esto:
uint32_t v4full=*((uint32_t*)v4);
y compilar usando -O3 -Wall
(Estoy usando gcc) obtendrá la advertencia:
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
Entonces no puedes evitar usar los turnos.
Nota: va a trabajo en configuraciones de optimización más bajas, y también funcionará en configuraciones más altas si nunca cambia el puntero de información a por v4
y v4_full
. Funcionará, pero sigue siendo un error y sigue "en contra de las reglas".
Si v4full es un puntero, entonces la línea
uint32_t *v4full;
v4full=( uint32_t)&v4;
Debería arrojar un error o al menos una advertencia del compilador. Tal vez quieras hacer
uint32_t *v4full;
v4full=( uint32_t *) v4;
Donde asumo v4
es en sí mismo un puntero a un uint8
array. Me doy cuenta de que estoy extrapolando información incompleta ...
EDITAR Dado que lo anterior parece haber solucionado un error tipográfico, intentemos de nuevo.
El siguiente fragmento de código funciona como se esperaba, y creo que desea que su código funcione. Por favor comente sobre esto: ¿cómo este código no hace lo que usted desea?
#include
#include
int main(void)
uint8_t v4[4] = 1,2,3,4;
uint32_t *allOfIt;
allOfIt = (uint32_t*)v4;
printf("the number is %08xn", *allOfIt);
Producción:
the number is 04030201
Nota: el orden de los bytes en el número impreso se invierte: obtiene 04030201
en vez de 01020304
como habrías esperado / querido. Esto se debe a que mi máquina (arquitectura x86) es little-endian. Si desea asegurarse de que el orden de los bytes sea el que desea (en otras palabras, ese elemento [0] corresponde al byte más significativo) es mejor usar la solución de @ bvj, cambiando cada uno de los cuatro bytes a la posición correcta en su entero de 32 bits.
Por cierto, puede ver esta respuesta anterior como una forma muy eficiente de hacer esto, si es necesario (diciéndole al compilador que use una instrucción incorporada de la CPU).
Recuerda que tienes concesión de aclarar tu experiencia si te fue de ayuda.