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")
关于LPCSTR
和LPWCSTR
:它们现在等同于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编写适配器。