Pase char * al método que espera unsigned char *

Estoy trabajando en algún dispositivo integrado que tiene SDK. Tiene un método como:

MessageBox(u8*, u8*); // u8 is typedefed unsigned char when I checked 

Pero he visto en sus ejemplos el código de llamadas como:

 MessageBox("hi","hello"); 

Pasando el puntero del char sin reparto. ¿Puede esto estar bien definido? Lo pregunto porque ejecuté alguna herramienta sobre el código y se quejaba de la falta de coincidencia anterior:

 messageBox("Status", "Error calculating \rhash"); diy.c 89 Error 64: Type mismatch (arg. no. 1) (ptrs to signed/unsigned) diy.c 89 Error 64: Type mismatch (arg. no. 2) (ptrs to signed/unsigned) 

A veces tengo diferentes opiniones sobre esta respuesta y esto me confunde aún más. Entonces, para resumir, usando su API de la manera descrita anteriormente, ¿es este problema? ¿Se estrellará el progtwig?

¿Y también sería bueno escuchar cuál es la forma correcta y luego pasar la cadena a los métodos del SDK que esperan un unsigned char* sin unsigned char* sin causar una violación de restricción?

Es una violación de restricción, por lo que técnicamente no está bien definido, pero en la práctica no es un problema. Sin embargo, debes lanzar estos argumentos para silenciar estas advertencias. Una alternativa a ensuciar su código con conversiones feas es definir una función en línea:

 static inline unsigned char *ucstr(const char *str) { return (unsigned char *)str; } 

Y use esa función donde sea que necesite pasar cadenas a las API que (erróneamente) toman argumentos unsigned char * :

 messageBox(ucstr("hi"), ucstr("hello")); 

De esta manera no recibirá advertencias mientras mantiene algún tipo de seguridad.

También tenga en cuenta que messageBox debe tomar const char * argumentos. Este SDK utiliza convenciones cuestionables.

El problema se reduce a que esté definido por la implementación si char está unsigned o signed .

Los comstackdores para los que no hay error serán aquellos para los que char está realmente unsigned . Algunos de ellos (especialmente los que son en realidad comstackdores de C ++, donde char y unsigned char son tipos distintos) emitirán una advertencia. Con estos comstackdores, la conversión del puntero a un unsigned char * será segura.

Los comstackdores que informen un error serán aquellos para los que se ha signed . Si el comstackdor (o el host) utiliza un conjunto de caracteres ASCII o similar, y los caracteres de la cadena son imprimibles, entonces la conversión se convierte en caracteres unsigned char * (o, mejor, en caracteres const unsigned char * que evita la const de los literales de cadenas ) es técnicamente seguro. Sin embargo, esas conversiones son potencialmente inseguras para implementaciones que usan juegos de caracteres diferentes O para cadenas que contienen caracteres no imprimibles (por ejemplo, valores de tipo con signed char que son negativos y valores de unsigned char mayores que 127). Digo potencialmente inseguro, porque lo que sucede depende de lo que hace la función llamada, por ejemplo, ¿comprueba los valores de los caracteres individuales? ¿comprueba los bits individuales de caracteres individuales en la cadena? El último es, si la función llamada está bien diseñada, una razón por la que aceptará un puntero a unsigned char * .

Por lo tanto, lo que debe hacer se reduce a lo que puede suponer acerca de la máquina de destino, y sus tipos de caracteres de tipo char y unsigned char , y qué hace la función con su argumento. El enfoque más general (en el sentido de que funciona para todos los conjuntos de caracteres, e independientemente de si el unsigned está signed o unsigned ) es crear una función auxiliar que copia la matriz de caracteres a una matriz diferente de caracteres unsigned char . El funcionamiento de esa función auxiliar dependerá de cómo (y si) necesita manejar la conversión de valores signed char con valores negativos.