elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


 


Tema destacado: Sigue las noticias más importantes de elhacker.net en ttwitter!


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse)
| | |-+  de wchar_t a unsigned char
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: de wchar_t a unsigned char  (Leído 752 veces)
pikoc

Desconectado Desconectado

Mensajes: 15


Ver Perfil
de wchar_t a unsigned char
« en: 20 Mayo 2015, 10:57 »

Hola:
Tengo una cadena wchar_t y tengo que pasarla a unsigned char, no me lo permite de ninguna manera, buscando en San Google, he encontrado esto:

Citar
unsigned char * dirNameA = reinterpret_cast<unsigned char *>(dirName.c_str());

That might not work because c_str returns a const wchar_t *so you can also try:

unsigned char * dirNameA = reinterpret_cast<unsigned char *>(
                               const_cast<wchar_t *>(dirName.c_str())
                           );

Que lo he adaptado a mi código de la siguiente manera:

Citar
unsigned char  valor = reinterpret_cast<unsigned char >(const_cast<wchar_t >(princ));

Pero sigo sin conseguir nada... bueno, más que no conseguir nada, me da el siguiente error:

error C2440: 'const_cast' : no se puede realizar la conversión de 'wchar_t' a 'wchar_t'

Alguien me puede ayudar?


« Última modificación: 20 Mayo 2015, 11:00 por pikoc » En línea

Peregring-lk

Desconectado Desconectado

Mensajes: 50


Ver Perfil
Re: de wchar_t a unsigned char
« Respuesta #1 en: 20 Mayo 2015, 15:44 »

No he visto tu código original, pero seguramente, el ejemplo que has pillado sería equivalente al siguiente:

Código
  1. const wchar_t* wstr = /* lo que sea */; // Cadena const.
  2. unsigned char* ustr = reinterpret_cast<unsigned char*>(const_cast<wchar_t*>(wstr));

Sin embargo, tú tendrás lo siguiente:

Código
  1. wchar_t* wstr = /* lo que sea */; // Cadena no-const.
  2. unsigned char* ustr = reinterpret_cast<unsigned char*>(const_cast<wchar_t*>(wstr));

El error está en el `const_cast`. El `const_cast` sirve para quitar/poner el calificativo `const` a un puntero o una referencia. Ejemplos:

Código
  1. int a = 3;
  2.  
  3. // Ok, const_cast recibe un puntero (int*) y lo convierto a puntero-a-constante (const int*).
  4. const int* ptr_a = const_cast<const int*>(&a);
  5. const int* ptr2_a = &a; // Ok, la conversion a const tambien funciona de forma implicita.
  6.  
  7. // Aqui el `const_cast` es absolutamente necesario. Quitarle `const` a un puntero/referencia nunca
  8. // es implicito (ponerselo si), y hay que forzarlo con `const_cast`.
  9. int* ptr3_a = const_cast<int*>(ptr_a);
  10.  
  11. // Este es el error de tu codigo! `ptr3_a` no es constante, y el tipo de salida del casting, tampoco (int*),
  12. // pero `const_cast` requiere que uno de los dos sea constante y el otro no! Si los dos son iguales
  13. // te da un error de compilacion.
  14. int* ptr4_a = const_cast<int*>(ptr3_a);

No he puesto ejemplos con referencias porque no es tu caso. ¿Cuál es tu problema? Que tu `const_cast<wchar_t*>(wstr)` está diciendo: "quítale el `const` a `wstr`", pero `wstr` resulta que no es `const`, así que no hay nada que quitar, y de ahí el error de compilación. De todas formas, utilizar un `const_cast` es peligroso, y podría provocar incluso violaciones de segmento (especialmente con cadenas). Si algo se marco como `const`, es por algo.

Bueno, continuemos. ¿Y qué es lo que hace `reinterpret_cast<tipo>(var)`? Pues sencillamente lo siguiente: coje la dirección de memoria de la variable que le has pasado, y a partir de ahí, coje `sizeof(tipo)` bytes y lo devuelve como un objeto de tipo `tipo`. Ajin! Completamente a pelo, y éso es muy peligroso.

Por ejemplo (relacionandolo con tu caso):

Código
  1. wchar_t wc = /* un caracter, el que sea */
  2. unsigned char c = reinterpret_cast<unsigned char>(wc);

Veamos el peligro: al menos en mi arquitectura, `sizeof(wc) == 4`, mientras que `sizeof(char) == 1`. Al realizar dicho `reinterpret_cast`, el compilador coje el primer byte the `wc` y devuelve la secuencia de bits como un `unsigned char`, sin adaptar la representación ni nada, y `c` tendría una copia del primer byte the `wc`.

¿Qué pasa con cadenas/punteros?

Código
  1. wchar_t* wc = /* lo que sea. Cadena de 5 caracteres. */
  2. unsigned char* c = reinterpret_cast<unsigned char*>(wc);

Aquí `wc` es un puntero (y todos los punteros tienen el mismo tamaño en una misma arquitectura), así que `reinterpret_cast`  devuelve la misma dirección de memoria, pero ahora desde `c` estás manipulando `unsigned char`s y no `wchar_t`s. Así que:

Código
  1. for (unsigned i = 0; i < 5; ++i)
  2.    cout << c[i] << endl;

Aquí, tu crees que estás imprimiendo los 5 primeros carácteres de la cadena original (transformada como `unsigned char`), pero resulta que estás imprimiendo ¡los 4 primeros bytes del primer carácter de la cadena `wchar_t` original, más el primer byte de la segunda! Habría que hacerlo de la siguiente forma:

Código
  1. for (unsigned i = 0; i < 5 * sizeof(wchar_t); ++i)
  2.    cout << c[i] << endl;

Además, utilizarlo de la siguiente forma tiene muchos riesgos, el más importante es que `wchar_t` es un tipo muy especial, cuya implementación es a gusto del compilador, así que en teoría, no hay forma de saber cómo está representado cada carácter. ¿Están los bytes puestos de abajo a arriba? ¿De arriba a bajo? ¿Con complemento a uno o a dos? ¿Cada carácter tiene 2 bytes, 4 u 8?

Así que, si trabajar con `reinterpret_cast` es peligroso de por sí (solo debe usarse en situaciones muy controladas), y utilizarlo para llegar de `wchar_t` a `char` lo es más aún.

Siempre que puedas, utiliza `char*`, a no ser que sea exclusivamente necesario.


« Última modificación: 20 Mayo 2015, 15:56 por Peregring-lk » En línea

pikoc

Desconectado Desconectado

Mensajes: 15


Ver Perfil
Re: de wchar_t a unsigned char
« Respuesta #2 en: 21 Mayo 2015, 16:54 »

Osea... que estoy Jod%$#...
Sí, es totalmente necesario que utilice wchar_t, ya que yo recibo datos del puerto serie, y esos datos son guardados en una cadena tipo string, luego los paso a wchar_t para poder interpretarlos y que se interpreten bien en todo el código, pero no hay manera de verlos bien representados de otra manera.
Te comento; he quitado todo esto del reinterpret_cast y del const_cast y los he dejado con wchar_t en todos lados y va bien... el problema está al usar funciones externas que vienen dadas y supongo que es por lo que decías tú de cómo se ordenan los datos en el wchar_t.
Gracias
Seguiré buscando...  >:(
En línea

pikoc

Desconectado Desconectado

Mensajes: 15


Ver Perfil
Re: de wchar_t a unsigned char
« Respuesta #3 en: 21 Mayo 2015, 17:06 »

Pero igualmente, conoces alguna manera de poder pasar (de modo seguro... ) de wchar_t a char??????
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Pasar de char a unsigned int en Dev-C++?
Programación C/C++
Riki_89D 5 7,421 Último mensaje 10 Septiembre 2009, 03:59
por aguml
convertir char a wchar_t
Programación C/C++
Riki_89D 3 3,206 Último mensaje 1 Junio 2010, 09:27
por Eternal Idol
Estructura ARP a buffer unsigned char *
Programación C/C++
ahkbar87 3 1,406 Último mensaje 3 Febrero 2012, 01:44
por ahkbar87
Problema conversión Unsigned char a char
Programación C/C++
juliodiez 4 1,054 Último mensaje 19 Enero 2013, 04:34
por juliodiez
Ayuda por favor! Con c, unsigned char y array de char !
Programación C/C++
Yurasamai 1 524 Último mensaje 24 Noviembre 2015, 09:14
por avesudra
Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines