使用Windows API配置串行端口:CreateFile失败,错误2(ERROR_FILE_NOT_FOUND)

时间:2017-12-29 22:22:00

标签: c++ visual-studio winapi serial-port visual-studio-2017

我试图创建一个C ++程序,在Windows 7的Visual Studio社区2017中使用Windows API与串行端口设备进行通信。在MSDN上运行this示例,只需更改一次 - 使用:< / p>

const wchar_t *pcCommPort = TEXT("\\.\COM16"); //  Most systems have a COM1 port

而不是这个(否则它不会编译):

TCHAR *pcCommPort = TEXT("COM1"); //  Most systems have a COM1 port

我收到CreateFile错误2(ERROR_FILE_NOT_FOUND)。我很不知道这里出了什么问题。

以下是代码:

#include "stdafx.h"

void PrintCommState(DCB dcb)
{
    //  Print some of the DCB structure values
    _tprintf(TEXT("\nBaudRate = %d, ByteSize = %d, Parity = %d, StopBits = %d\n"),
        dcb.BaudRate,
        dcb.ByteSize,
        dcb.Parity,
        dcb.StopBits);
}


int _tmain(int argc, TCHAR *argv[])
{
    DCB dcb;
    HANDLE hCom;
    BOOL fSuccess;
    const wchar_t *pcCommPort = TEXT("\\.\COM16"); //  Most systems have a COM1 port

                                      //  Open a handle to the specified com port.
    hCom = CreateFile(pcCommPort,
        GENERIC_READ | GENERIC_WRITE,
        0,      //  must be opened with exclusive-access
        NULL,   //  default security attributes
        OPEN_EXISTING, //  must use OPEN_EXISTING
        0,      //  not overlapped I/O
        NULL); //  hTemplate must be NULL for comm devices

    if (hCom == INVALID_HANDLE_VALUE)
    {
        //  Handle the error.
        printf("CreateFile failed with error %d.\n", GetLastError());
        system("PAUSE");
        return (1);
    }

    //  Initialize the DCB structure.
    SecureZeroMemory(&dcb, sizeof(DCB));
    dcb.DCBlength = sizeof(DCB);

    //  Build on the current configuration by first retrieving all current
    //  settings.
    fSuccess = GetCommState(hCom, &dcb);

    if (!fSuccess)
    {
        //  Handle the error.
        printf("GetCommState failed with error %d.\n", GetLastError());
        return (2);
    }

    PrintCommState(dcb);       //  Output to console

                               //  Fill in some DCB values and set the com state: 
                               //  57,600 bps, 8 data bits, no parity, and 1 stop bit.
    dcb.BaudRate = CBR_9600;     //  baud rate
    dcb.ByteSize = 8;             //  data size, xmit and rcv
    dcb.Parity = NOPARITY;      //  parity bit
    dcb.StopBits = ONESTOPBIT;    //  stop bit

    fSuccess = SetCommState(hCom, &dcb);

    if (!fSuccess)
    {
        //  Handle the error.
        printf("SetCommState failed with error %d.\n", GetLastError());
        return (3);
    }

    //  Get the comm config again.
    fSuccess = GetCommState(hCom, &dcb);

    if (!fSuccess)
    {
        //  Handle the error.
        printf("GetCommState failed with error %d.\n", GetLastError());
        return (2);
    }

    PrintCommState(dcb);       //  Output to console

    _tprintf(TEXT("Serial port %s successfully reconfigured.\n"), pcCommPort);
    return (0);
}

2 个答案:

答案 0 :(得分:1)

two different defines控制ANSI / Unicode字符:

#define UNICODE控制Windows SDK API(LPTSTRTEXT

#define _UNICODE控制C运行时间(TCHAR_TEXT_T

您通常不会定义任何一项或两项,如果您不必使用正确的组合:

const TCHAR* cstr = _T("Hello");
LPCTSTR winstr = TEXT("World");

您的代码的另一个问题是您使用的是TCHAR*而不是const TCHAR*。根据您的编译器版本和开关,文字字符串可能位于二进制文件的只读数据部分中,因此请确保该类型是指向常量字符串的指针。

如果您仍然不确定尺寸,可以这样做:

LPCTSTR x;
printf("TEXT=%d LPCTSTR=%d _T=%d TCHAR=%d\n", sizeof(TEXT("")), sizeof(*x), sizeof(_T("")), sizeof(TCHAR));

我刚刚在带有COM端口的虚拟机上进行了测试,并且普通名称工作正常:

LPCTSTR pcCommPort = TEXT("COM1"); 
HANDLE hCom = CreateFile(pcCommPort,
        GENERIC_READ | GENERIC_WRITE,
        0,      //  must be opened with exclusive-access
        NULL,   //  default security attributes
        OPEN_EXISTING, //  must use OPEN_EXISTING
        0,      //  not overlapped I/O
        NULL); //  hTemplate must be NULL for comm devices

如果您想使用COM port above 9,则必须使用Win32 device path语法:

LPCTSTR pcCommPortWin32DevicePath = TEXT("\\\\.\\COM16"); 
HANDLE hCom = CreateFile(pcCommPortWin32DevicePath, ...);

(MSDN描述了它应该在内存中查找的字符串,而不是代码中的字符串。您对此的线索是示例字符串中的单斜杠。这意味着您必须将所有反斜杠加倍才能获得正确的C字符串。)< / p>

答案 1 :(得分:0)

您需要在字符串文字中转义反斜杠,例如

const TCHAR *pcCommPort = TEXT("\\\\.\\COM16");