我有api功能。我接受一个指向数组char的指针。调用功能不受我的控制。数组是动态的,但仍需要一些检查
extern "C" int __stdcall calcW2(LPWSTR foo)
如果有人打电话
char foo[5000];
LPSTR lpfoo2 = foo;
calcW2(lpfoo2 );
我明白我需要做一些检查。我可以测试nulltpr。但是,如果我想要检查。 char数组有一定的有效性。怎么做得最好?以最安全的方式将字符串设置为0到2500个字符。是否需要检查更多内容?
if(foo != nullptr)
{
//Size checking
//size_t newsize = strlen(SerialNumber) + 1 not good?
std::wstring test(foo);
}
答案 0 :(得分:0)
你错过了一个重点。函数签名表示LPWSTR
不是LPSTR
。这意味着函数期望(或应该期望)接收wchar_t[]
而不是char[]
。请参阅https://msdn.microsoft.com/en-us/library/cc230355.aspx。
我的意思是:
extern "C" int __stdcall calcW2(LPWSTR foo) <--- LP-W-STR
char foo[5000];
LPSTR lpfoo2 = foo; <--- LP-STR
calcW2(lpfoo2 ); <--- LP-STR passed into LP-W-STR ??
不应该编译。参数类型是错误的。
如果将数组更改为wchar_t []并且它开始无法编译,那么很可能你有一些_UNICODE #defines设置错误。在WINAPI等中,许多函数都有双重定义。什么时候&#34; UNICODE&#34;如果设置了标志,它们会接受LPWSTR,但是当标志被清除时,标头会将它们切换为LPSTR。因此,如果您发现它应该是LPWSTR并且您希望它是LPWSTR并且它仍然坚持LPSTR,那么您要么搞砸了函数名称,要么使用UNICODE标记(或者您拥有的标题是不正确的)。
char和wchar_t是不同的。简化,char是&#34;单字节&#34;和wchar_t是&#34; twobyte&#34;。两者都使用&#39; \ 0&#39;作为字符串结束标记,但在wchar_t中实际上是&#39; \ 0 \ 0&#39;因为每个字符有两个字节。此外,在wchar_t []中,纯ASCII数据不像a|b|c|d|e|f
,它是0|a|0|b|0|c|0|d|0|e|0|f
,因为它是每个字符的两个字节。这就是strlen
无法正确处理16位编码数据的原因 - 它从第一个字符中选择第一个\ 0作为字符串结尾。将wchar_t数据强制打包到char []中显然是错误的,或者至少是非常误导和容易出错。
这就是为什么你应该使用wstrlen
代替wchar_t*
而不是char*
。
这是一项总体规则&#39;。对于任何处理char的函数(strlen,strcat,strcmp,..),你应该能够找到相关的w *函数(wstrlen,wstrcat,wstrcmp,..)。有时候名字中可能会有一些下划线。搜索文档。不要混淆char类型。那现在只是字节数组。它们有一些语义,通常如果某些类型的命名方式不同,那就是原因。