我正在学习教程 here与串口通信
打开和关闭串口的主要代码如下:
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
消息)
在玩了一会儿代码后,我发现 CreateFileA()
成功打开串口(我什至发现这个的唯一原因是因为当我用谷歌搜索 CreateFile ()
函数 我得到了 CreateFileA()
的 MSDN 定义页作为第一个结果
我用谷歌搜索,但找不到两者之间的区别。我找到了 this ,它说我应该始终 CreateFile()
并且编译器应该完成其余的工作,但它在我的情况下不起作用,只有在我专门使用 CreateFileA()
时才起作用
CreateFile()
和 CreateFileA()
之间有什么区别,我应该在我的程序中使用哪一个来进行基本的串行端口通信?
Windows 10
Visual Studio 2013 速成版
最佳答案
这里需要对 Windows API 进行一些解释:Microsoft 很早就引入了 Unicode。当时,他们决定用 16 位表示 Unicode 字符。我想这在当时是一个有效的决定。因此,Microsoft 平台上的 wchar_t
为 16 位宽,(Unicode) 文本存储在 wchar_t
中——这具有每个字符宽度相等的优点。缺点是处理 char
的现有 API 不再兼容。
如今,使用 32 位 Unicode 代码点,这看起来很傻——Microsoft 平台上的 Unicode 文本使用 UTF-16 编码,因此您有两个缺点:与简单的基于 char
的字符串不兼容 < strong> 和 多字符序列。在许多其他平台上,wchar_t
是 32 位宽,Unicode 要么存储在这些 wchar_t
中,要么在“普通”char
中编码为 UTF-8 >s.
但回到 Microsoft API:为了解决这个问题,他们将所有处理字符串的 API 调用重命名为带有 A
后缀,并引入了第二组相同的调用,采用 wchar_t
,后缀为 W
表示 Unicode 变体。根据编译时开关 UNICODE
,预处理器将原始名称映射到具有任一后缀的真实名称。
您可能知道,C 语言中的字符串文字具有 char *
类型。要生成 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 的不同处理(wchar_t
在 Windows 上,char
在大多数其他系统上使用 UTF-8, UTF-8 在 Internet 上也占主导地位)。
为此,我更喜欢始终定义 UNICODE
,对 Windows API 所需的任何常量字符串使用 wchar_t
字符串文字(例如您的 CreateFile( )
调用,因此只需在它前面加上 L
) 并使用 UTF-8 在内部将所有字符串存储在 char
中,仅在需要将它们传递给Windows API。有两个函数可以进行转换:MultiByteToWideChar()
和 WideCharToMultiByte()
.这样,您就可以轻松地为其他使用 UTF-8 的操作系统的 API 编写适配器。
关于c - CreateFile() 和 CreateFileA() 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51462048/