将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使用可疑的约定。
问题归结为实现定义char
是unsigned
还是有signed
。
没有错误的编译器将是char
实际上unsigned
编译器。 其中一些(特别是那些实际上是C ++编译器,其中char
和unsigned char
是不同的类型)将发出警告。 使用这些编译器,将指针转换为unsigned char *
将是安全的。
报告错误的编译器将是实际signed
char
编译器。 如果编译器(或主机)使用ASCII或类似的字符集,并且字符串中的字符是可打印的,那么将字符串转换为unsigned char *
(或者更好的是,转换为const unsigned char *
,以避免从字符串文字中删除常量)技术上是安全的。 但是,对于使用不同字符集的实现,或者对于包含不可打印字符的字符串,这些转换可能不安全(例如,类型为signed char
值为负数, unsigned char
值大于127)。 我说可能不安全,因为发生的事情取决于被调用函数的作用 – 例如它是否检查单个字符的值? 它会检查字符串中各个字符的各个位吗? 后者是,如果被调用的函数设计得很好,它将接受指向unsigned char *
的指针的一个原因。
因此,您需要做的就是您可以对目标机器及其char
和unsigned char
类型所假设的内容以及函数对其参数的作用。 最通用的方法(在某种意义上它适用于所有字符集,无论char
是有signed
还是unsigned
)都是创建一个辅助函数,它将char
数组复制到另一个unsigned char
数组。 该辅助函数的工作将取决于您需要如何(以及如果)处理带有负值的signed char
值的转换。