使用 Win32 API 时,要使用哪些数据类型?
Posted
技术标签:
【中文标题】使用 Win32 API 时,要使用哪些数据类型?【英文标题】:When using the Win32 API, which data types to use? 【发布时间】:2014-03-20 20:40:16 【问题描述】:标准数据类型还是 Windows 数据类型?
我会使用 Windows 数据类型来使我的代码与 Win32 API 保持一致。
另一方面,我会更多地使用标准数据类型来防止编码错误。
-
使用 nullptr 而不是 NULL 可以防止为实际上不采用指针类型的参数传递 NULL 的不良风格。
想象一个 Win32 API 函数,它出于某种无意义的原因采用 LPTSTR,但实际上将其视为 LPTCSTR。你有一个 std::string,然后执行 (LPTSTR)(s.c_str())。一切都很好,直到您切换到 W 版本的 Win32 API 函数。该程序编译是因为强制转换成功,但可能会发生一些不好的事情。如果你已经完成了 (char*)(s.c_str()),编译器就会捕捉到这一点。
使用标准数据类型似乎更安全,但也感觉像是去参加一个全黑的“穿白”派对。
这里应该决定什么?
【问题讨论】:
对于#2,我知道很少有 API 采用LPTSTR
而不期望它应该是可变的。它们存在,但谢天谢地,它非常罕见。如果您想完全符合std::vector<TCHAR> tmp(s.begin(), s.end()); tmp.push_back(TCHAR());
的标准,那么发送tmp.data()
会起作用,但我同意有时保持完全合规会很痛苦。如果字符串的 char 类型与 TCHAR 不一致,则 temp 方法将正确编译失败。无论如何,我同意,并且不会 hard-c-ctyle cast。
You have a std::string, and do (LPTSTR)(s.c_str()).
如果你这样做了,代码永远不会通过审查。
我认为这是一个很好的问题,可能会引发一些很好的讨论,但我认为 Stack Overflow 不是适合它的论坛。你会得到很多意见。
@PaulMcKenzie,没有。但有时程序员会犯错误,甚至审稿人也可能没有发现。
最好避免假设这些 typedef 具有某种魔力并且与编译器使用的类型不匹配。 LPTSTR 只是 char* ,因此不需要强制转换。等到变成 wchar_t* 的那一天是不明智的,30 亿客户已经等不及了。
【参考方案1】:
这在很大程度上取决于您正在从事的项目。尝试遵循已经建立的编码风格。
我最喜欢的做事方式:
对于我声明的方法,我使用普通数据类型(void*
、char*
等...),当我调用它们时,我也使用它。
但是,对于我与 Win32 API 进行的每次交互,我要么将变量声明为 Win32 API 样式(LPVOID
,LPTSTR
,...),要么从我的一个函数(其中具有“正常”数据类型),但需要转到 Win32 API 调用,我专门将类型转换为所需的类型。有时这也有助于查看我是否有一些冲突的类型。
【讨论】:
这似乎是个好主意。让我澄清一下。 f(const char* a) 并在 f 里面写 LPCSTR b = a; ToWinApi(b); ? 是的,没错。而且您甚至不需要第二个变量,只需执行以下操作:ToWinApi ( (LPCSTR)(a) );
这样您就会看到您的const char*
确实映射到LPCSTR
而不是LPTSTR
【参考方案2】:
hmm - 我认为 winapi 的 constness 非常好。你有例子吗?
但是对于你的问题:
我建议为你自己的东西使用 stdint 类型但是在与 winAPI 交互时使用它们的类型并相互转换以避免类型宽度的困难和混淆例如 WORD 的含义。
【讨论】:
【参考方案3】:Windows 与 C++ 类型与 Unicode 安全完全正交。
如果您有std::string s
,那么您可以使用const_cast<LPSTR>(s.c_str())
,而不会在编译为Unicode 时牺牲编译器错误。
【讨论】:
【参考方案4】:我同意@fritzone 作为一个实用的解决方案。我的略有不同。
我非常喜欢封装外部 API。我将编写一层代码,在其中使用 WinApi,并始终在该层内使用 Windows 类型。这将是包含 Windows.h 的应用程序的唯一部分。对这些层函数的 API 调用将使用我选择的类型,并且(对于 @fritzone)我将根据需要将值显式转换为 WIndows 类型。每一个演员都是一个等待发生的错误。
分层的另一个优点是它是放置跟踪代码的好地方。 WinApi 可能非常健谈且难以在调试器中单步执行,因此我喜欢为每个 WinApi 函数提供跟踪代码,如果需要可以打开。
使用 MFC 或 ATL 更难做到这一点,它们往往变得相当普遍。这是我对各种不同的外部 API 的偏好。
【讨论】:
以上是关于使用 Win32 API 时,要使用哪些数据类型?的主要内容,如果未能解决你的问题,请参考以下文章
Win32 API 事件 - 它在跨不同进程的访问方面都有哪些限制?
C# call Win32 api时,-1如何转换为DWORD