c++ - 使用 CSerial (C++) 打开虚拟 COM 端口

标签 c++ winapi visual-c++ serial-port

我正在使用 Ramon de Klein's CSerial library为了从我的 C++ 代码打开和管理串行端口。

我的硬件实现了带有 FTDI 芯片的串行 tu USB 转换器,因此我能够将串行端口连接到我 CPU 中的 USB 插头。安装 FTDI 驱动程序后,虚拟 COM 端口将显示在“设备管理器”(Windows) 中。

如果我尝试打开它,它会起作用。

但现在我已经安装了 USB 到以太网服务器,如 this one .所以我安装了它的驱动程序和软件,并在将一些 USB 设备连接到它之后,它被检测到并作为虚拟串行端口添加到“设备管理器”窗口。

但是当我尝试打开端口时,它不起作用。 如果我使用类似 HyperTerminal 的应用程序打开该端口,它确实可以工作,就好像它是一个普通的串行端口一样,但在我的代码中没有。

CSerial 库就像在创建一个新文件一样工作,并且给定的 LastErrorCode 为 2:“找不到文件”。这是 CSerial 库中的 Open 方法:

LONG CSerial::Open (LPCTSTR lpszDevice, DWORD dwInQueue, DWORD dwOutQueue, bool fOverlapped)
{
    // Reset error state
    m_lLastError = ERROR_SUCCESS;

    // Check if the port isn't already opened
    if (m_hFile)
    {
        m_lLastError = ERROR_ALREADY_INITIALIZED;
        _RPTF0(_CRT_WARN,"CSerial::Open - Port already opened\n");
        return m_lLastError;
    }

    // Open the device
    m_hFile = ::CreateFile(lpszDevice,
                           GENERIC_READ|GENERIC_WRITE,
                           0,
                           0,
                           OPEN_EXISTING,
                           fOverlapped?FILE_FLAG_OVERLAPPED:0,
                           0);
    if (m_hFile == INVALID_HANDLE_VALUE)
    {
        // Reset file handle
        m_hFile = 0;

        // Display error
        m_lLastError = ::GetLastError();
        _RPTF0(_CRT_WARN, "CSerial::Open - Unable to open port\n");
        return m_lLastError;
    }

#ifndef SERIAL_NO_OVERLAPPED
    // We cannot have an event handle yet
    _ASSERTE(m_hevtOverlapped == 0);

    // Create the event handle for internal overlapped operations (manual reset)
    if (fOverlapped)
    {
        m_hevtOverlapped = ::CreateEvent(0,true,false,0);
        if (m_hevtOverlapped == 0)
        {
            // Obtain the error information
            m_lLastError = ::GetLastError();
            _RPTF0(_CRT_WARN,"CSerial::Open - Unable to create event\n");

            // Close the port
            ::CloseHandle(m_hFile);
            m_hFile = 0;

            // Return the error
            return m_lLastError;
        }
    }
#else

    // Overlapped flag shouldn't be specified
    _ASSERTE(!fOverlapped);

#endif

    // Setup the COM-port
    if (dwInQueue || dwOutQueue)
    {
        // Make sure the queue-sizes are reasonable sized. Win9X systems crash
        // if the input queue-size is zero. Both queues need to be at least
        // 16 bytes large.
        _ASSERTE(dwInQueue >= 16);
        _ASSERTE(dwOutQueue >= 16);

        if (!::SetupComm(m_hFile,dwInQueue,dwOutQueue))
        {
            // Display a warning
            long lLastError = ::GetLastError();
            _RPTF0(_CRT_WARN,"CSerial::Open - Unable to setup the COM-port\n");

            // Close the port
            Close();

            // Save last error from SetupComm
            m_lLastError = lLastError;
            return m_lLastError;    
        }
    }

    // Setup the default communication mask
    SetMask();

    // Non-blocking reads is default
    SetupReadTimeouts(EReadTimeoutNonblocking);

    // Setup the device for default settings
    COMMCONFIG commConfig = {0};
    DWORD dwSize = sizeof(commConfig);
    commConfig.dwSize = dwSize;
    if (::GetDefaultCommConfig(lpszDevice,&commConfig,&dwSize))
    {
        // Set the default communication configuration
        if (!::SetCommConfig(m_hFile,&commConfig,dwSize))
        {
            // Display a warning
            _RPTF0(_CRT_WARN,"CSerial::Open - Unable to set default communication configuration.\n");
        }
    }
    else
    {
        // Display a warning
        _RPTF0(_CRT_WARN,"CSerial::Open - Unable to obtain default communication configuration.\n");
    }

    // Return successful
    return m_lLastError;
}

我不明白为什么它的工作方式与将 USB 直接插入计算机的方式不同:我一直认为如果 COM 列在“设备管理器”中,它应该可以工作,而不管它在哪里真正联系在一起。

总的来说,数据的来源是:

RS232--->转USB--->USB CPU连接器--->在COM口虚拟为RS232

现在是:

RS232--->转换为USB--->通过“netUSB服务器”转换为以太网--->CPU上的以太网/WiFi--->虚拟化为USB设备--->在COM端口中虚拟为RS232

有什么帮助吗?

最佳答案

出现问题不是因为硬件元素,而是因为分配给 COM 端口的编号。

当 COM 端口大于 9 时,CreateFile 函数无法打开设备,并返回一个 INVALID_HANDLE_VALUE。

报错,报解决方案here .

关于c++ - 使用 CSerial (C++) 打开虚拟 COM 端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11719093/

相关文章:

创建独立的隐藏进程

winapi - 在 GDI 中旋转矩形

winapi - 枚举在Windows XP上记录或回放的过程

c++ - 为什么要调用基础构造函数?

c++ - 在 VC++ 中通过 C++ 代码访问 GUI 组件

c++ - 绕圆旋转时计算方向

c++ 编译 std::thread 示例与 scons

c++ - 为什么数组中对象的析构函数在被另一个对象替换时不被调用?

c++ - 万花筒教程找不到 header `ExecutorProcessControl.h`

c++ - 根据一些枚举值在编译时添加额外的方法