CreateFile()和CreateFileA()有什么区别?

我按照这里的教程与串口通信

打开然后关闭串口的主要代码如下:

HANDLE hComm; hComm = CreateFileA((LPCSTR)"COM8", //port name GENERIC_READ | GENERIC_WRITE, //Read/Write 0, // No Sharing NULL, // No Security OPEN_EXISTING,// Open existing port only 0, // Non Overlapped I/O // FILE_FLAG_NO_BUFFERING, // copied from the MFC version NULL); // Null for Comm Devices if (hComm == INVALID_HANDLE_VALUE){ DWORD err = GetLastError(); printf("Error in opening serial port\n"); printf("err = 0x%x\n", err); } else printf("opening serial port successful\n"); CloseHandle(hComm);//Closing the Serial Port 

如果我使用CreateFile()代码编译正常但串口未打开(我Error in opening serial port消息时Error in opening serial port

在玩了一段时间之后,我发现CreateFileA()成功打开了串口(我发现这个的唯一原因是因为当我用Google搜索CreateFile()函数时,我得到了CreateFileA()的MSDN定义页面CreateFileA()作为第一个结果

我用Google搜索,但我找不到两者之间的区别。 我找到了这个 ,它说我应该总是CreateFile() ,编译器应该完成剩下的工作,但它在我的情况下不起作用,只有当我专门使用CreateFileA()时才有效

CreateFile()CreateFileA()什么区别,我应该在程序中使用哪一个进行基本的串口通信?

Windows 10
Visual Studio 2013表达

这里需要对Windows API进行一些解释:微软很早就引入了Unicode。 那时,他们决定用16位代表一个Unicode字符。 我想当时这是一个有效的决定。 因此,Microsoft平台上的wchar_t是16位宽,(Unicode)文本存储在wchar_t – 这具有每个字符具有相等宽度的优点。 缺点是处理char现有API不再兼容。

如今,使用32位Unicode代码点,这看起来很愚蠢 – Microsoft平台上的Unicode文本使用UTF-16进行编码,因此您有两个缺点:不兼容简单的基于字符串的字符串多字符序列。 在许多其他平台上, wchar_t是32位宽,Unicode存储在这些wchar_t或者在“普通” char编码为UTF-8。

但是回到Microsoft API:为了解决这个问题,他们将所有处理字符串的API调用重命名为A后缀,并引入了第二组相同的调用,以wchar_t后缀,后缀为W 根据编译时交换机UNICODE ,原始名称将被预处理器映射到带有后缀的实名。

您可能知道,C中的字符串文字具有char *类型。 要创建类型为wchar_t *的字符串文字,需要在其wchar_t *加上L 为了在设置UNICODE时自动执行此操作,还提供了另一个宏: _T() 。 因此,您希望在代码中执行的操作是在_T()包装任何字符串文字,当定义UNICODE时,它将完全以L为前缀。

因此,这一行:

 hComm = CreateFileA((LPCSTR)"COM8" 

应改为:

 hComm = CreateFile(_T("COM8") 

关于LPCSTRLPWCSTR :它们现在等同于char *wchar_t * 。 所以铸造是不必要的。 这些名称的原因是向后兼容具有分段存储器和“远指针”的古代系统。 只要您不需要为win16编译代码,就忘了它们。


最后一个个人观点:Windows已经知道Unicode很长一段时间了(IIRC已经使用Win95),现在它已成为标准。 您不太可能想要定位不支持unicode的Windows系统。 你更希望编写一些可移植的代码,然后问题是对Unicode的不同处理(Windows上的wchar_t ,大多数其他系统上的UTF-8 char ,UTF-8在互联网上也占主导地位)。

为了解决这个问题,我更喜欢总是定义UNICODE ,对Windows API所需的任何常量字符串使用wchar_t字符串文字(比如你​​的CreateFile()调用,所以只用L前缀)并使用UTF-将所有字符串内部存储在char中8,只有在需要将它们传递给Windows API时才转换它们。 执行转换有两个函数: MultiByteToWideChar()WideCharToMultiByte() 。 这样,您可以轻松地为使用UTF-8的其他OS的API编写适配器。