将char *传递给期望unsigned char *的方法

我正在研究一些有SDK的嵌入式设备。 它有一个方法,如:

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

但我在他们的例子中看到调用代码如:

 MessageBox("hi","hello"); 

没有强制转换传递char指针。 这可以很明确吗? 我问,因为我在代码上运行了一些工具,它抱怨上面的不匹配:

 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) 

有时我对这个答案有不同的看法,这让我更加困惑。 总而言之,通过上述方式使用他们的API,这个问题是什么? 它会破坏程序吗?

而且,听到将字符串传递给期望unsigned char*而不会导致约束违规的SDK方法的正确方法会更好吗?

这是一种约束违规,所以从技术上讲它没有很好的定义,但在实践中,它不是一个问题。 但是你应该抛出这些论点来压制这些警告。 使用丑陋的强制转换乱丢代码的另一种方法是定义内联函数:

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

并在需要将字符串传递给API(错误地)取unsigned char *参数的地方使用该函数:

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

这样,在保持某些类型安全的同时,您不会收到警告。

另请注意, messageBox应该采用const char *参数。 此SDK使用可疑的约定。

问题归结为实现定义charunsigned还是有signed

没有错误的编译器将是char实际上unsigned编译器。 其中一些(特别是那些实际上是C ++编译器,其中charunsigned char是不同的类型)将发出警告。 使用这些编译器,将指针转换为unsigned char *将是安全的。

报告错误的编译器将是实际signed char编译器。 如果编译器(或主机)使用ASCII或类似的字符集,并且字符串中的字符是可打印的,那么将字符串转换为unsigned char * (或者更好的是,转换为const unsigned char * ,以避免从字符串文字中删除常量)技术上是安全的。 但是,对于使用不同字符集的实现,或者对于包含不可打印字符的字符串,这些转换可能不安全(例如,类型为signed char值为负数, unsigned char值大于127)。 我说可能不安全,因为发生的事情取决于被调用函数的作用 – 例如它是否检查单个字符的值? 它会检查字符串中各个字符的各个位吗? 后者是,如果被调用的函数设计得很好,它将接受指向unsigned char *的指针的一个原因。

因此,您需要做的就是您可以对目标机器及其charunsigned char类型所假设的内容以及函数对其参数的作用。 最通用的方法(在某种意义上它适用于所有字符集,无论char是有signed还是unsigned )都是创建一个辅助函数,它将char数组复制到另一个unsigned char数组。 该辅助函数的工作将取决于您需要如何(以及如果)处理带有负值的signed char值的转换。