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

时间:2018-07-22 04:29:35

标签: c visual-studio serial-port

我正在按照教程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()成功打开了串行端口(而我什至发现这的唯一原因是,当我在Google搜索CreateFile()函数时得到了CreateFileA()的MSDN定义页作为第一个结果

我在Google周围搜索,但是我找不到两者之间的区别。我找到了this,它说我应该始终CreateFile(),其余的应该由编译器来完成,但这在我的情况下不起作用,仅在我专门使用CreateFileA()

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

Windows 10
Visual Studio 2013 Express

1 个答案:

答案 0 :(得分:7)

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

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

但是回到Microsoft API:为了解决此问题,他们将所有处理字符串的API调用重命名为带有A后缀,并引入了第二组相同的调用,采用了wchar_t ,后缀为W的Unicode变体。取决于编译时开关UNICODE,预处理器会将原始名称映射为带后缀的实名。

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

因此,此行:

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-8将所有字符串内部存储在char中,仅在需要将它们传递给Windows API时进行转换。有两个函数可以进行转换:MultiByteToWideChar()WideCharToMultiByte()。这样,您可以轻松地为使用UTF-8的其他操作系统的API编写适配器。