我应该在DirectX中使用std::string还是Windows数据类型?

4

我现在正在一个基于DirectX的项目上工作,但遇到了一些问题。尽管DirectX SDK严重依赖于Windows数据类型如LPSTRLPCSTR等,但我使用自己的类时却使用了std::string,这让混合处理字符串看起来有点奇怪。虽然我的问题很模糊,请问你建议我是继续使用string还是使用不同字符串类型的Windows指针以保持一致性呢?


std::string 明显更易于使用,并且访问底层的 C 字符串只需要额外的几个字符。尽管如此,在 C++03 中,与 C 接口使用它要比在 C++11 中麻烦一些。 - chris
4
我建议在Windows上使用std::wstring。请参见std::wstring VS std::string - Jesse Good
请阅读:http://www.utf8everywhere.org/#how - qPCR4vir
3个回答

5

LPSTRchar*的别名,LCPSTRconst char*的别名,因此你的问题实际上听起来像是 "我应该使用C++字符串还是C字符串?"

嗯,C++ std::string有一个成员函数称为c_str()(或STL兼容的等效data()函数),返回一个(不可修改的)C字符串。因此,每当一个函数接受LPCTSTR时,可以将c_str()的输出作为参数提供。

我建议你尽可能使用C++ std::string,这样更安全。


为了完整起见,使用.data()&str[0]来获取char* - Rapptz
@Rapptz:写入由data()c_str()返回的缓冲区是未定义行为。而且据我所知,它们都返回const char * - Andy Prowl
@AndyProwl 我习惯使用 &str[0],即 char* str2 = &str[0];。我承认我不确定 data() 返回的是 const char* 还是 char* - Rapptz
@ChristianIvicevic:Jesse的建议是有效的,但你已经明确提到了LPSTRLPCSTR。这些都是基于char的定义。如果你不进行转换,就不能将wstring::c_str()的输出传递给接受LPCSTR的函数。但是,如果你的API接受LPWSTRLPCWSTR,或者它接受LPTSTR并且你的项目正在使用Unicode字符,则一定要使用std::wstring,因为Windows操作系统正在使用Unicode字符串,所以大多数情况下都会执行转换。 - Andy Prowl
1
@Rapptz,我希望我的问题能够帮助您澄清该领域中的一些缺失知识。只要不碰到空终止符,您可以使用&str[0]来修改缓冲区,而data()c_str()是等效的。还要注意,所有这些便利都仅适用于C++11,其中字符串缓冲区必须具有连续的字符。 - chris
显示剩余2条评论

2
在现代C++代码中,我会使用一个健壮的字符串类,比如`std::string`,或者更好的`std::wstring`来支持Windows下的Unicode UTF-16。然后,在API边界处可以将其转换成“原始”的C字符串。
要获取只读的“原始”C字符串指针,您可以使用`std::[w]string::c_str()`方法。
相反,如果您想修改`std::[w]string`缓冲区,您可以首先调用`resize()`方法来准备字符串缓冲区,使其足够大;然后,您可以使用`&str[0]`访问内部缓冲区,以便那些需要向其中写入的API调用。
请注意,在特定于Windows的代码中,ATL的`CString`是另一个方便的字符串类,您可能希望使用它。它有一些平台特定的方便设施,比如从资源加载字符串(这对应用程序本地化很有用)。
由于`CString`提供了一个隐式转换到`LPCTSTR`,您可以将`CString`实例直接传递给期望原始`LPCTSTR`的API。相反,如果您需要修改内部的`CString`缓冲区,您可以使用`GetBuffer()`/`ReleaseBuffer()`方法。

1

在@Andy Prowl的回答基础上,您可能希望使用"T"字符串编写所有代码(即使用LPTSTR而不是LPSTRLPWSTR)。T的确切类型(真正的TCHAR)是在编译时根据您是否定义了UNICODE_UNICODE #defined来设置的。这使您具有兼容性。

您仍然可以使用C++字符串来实现此技术,方法是从basic_string<>派生出一个tstring类:

typedef std::basic_string<TCHAR> tstring;

3
在现代的Win32 C++代码中,我会在Windows上仅使用UTF-16(在应用程序边界外,UTF-8也可以),并仅使用std::wstringwchar_t(或Unicode构建中对应的CStringW)而不是旧的ANSI / MBCS兼容的TCHAR模型。我认为在现代,TCHAR模型已经过时且无用。 - Mr.C64
好的观点。+1。但说到现代,Win32和DirectX怎么样了?新一代的编程语言(如C#)和API(如WPF)已经超越了它们,对吧?顺便说一句,@Mr.C64谈论过时性的讽刺感我可不会忽略。 :) - Randall Cook
1
说“已经超越了它们”没有意义,因为这些新技术是建立在旧技术之上的。它们今天仍然被广泛使用。然而,“TCHAR”除了用于旧代码库或向后兼容性外几乎没有其他用途。 - Jesse Good
哎呀!不要使用TCHAR,除非你需要支持Windows 98。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接