繁体   English   中英

C++ 串口 COM 端口访问

[英]C++ Serial COM Port Access

在 uPyCraft IDE 或 Putty 中,只需发送 km.press('a') 然后它工作正常,但在我的 C++ 中,我尝试使用 km.press('a') 写入文件,它不起作用。 我找不到问题所在

uPyCraft 成功

`bool CSerialPort::OpenPort(CString portname)
{
    m_hComm = CreateFile(L"//./" + portname,
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        0,
        0);
    if (m_hComm == INVALID_HANDLE_VALUE)
    {
        std::cout << "INVALID HANDLE" << std::endl;
        return false;
    }
    else
        return true;
}

bool CSerialPort::WriteByte(const char * bybyte)
{
    byte iBytesWritten = 0;
    if (WriteFile(m_hComm, &bybyte, 1, &m_iBytesWritten, NULL) == 0)
        return false;
    else
        return true;
}

int main()
{
CSerialPort _serial;

_serial.OpenPort(L"COM4");

_serial.WriteByte("km.press('a')");
}`

我试过了,

但它不起作用,我还检查了_serial Isn't INVALID HANDLE。

有人帮我发送"km.press('a')"到串行

并使用 Putty 和 uPyCraft 发送km.move(0,1)

它工作正常但是

string test = "km.move(0,1)";
DWORD dwBytesWritten;
WriteFile(m_hComm,&test,sizeof(test),dwBytesWritten,NULL);

它不起作用。 只是将km.move(0,1)更改为km.move(0,10) ,然后我不知道为什么但它工作正常。 uPyCraft(Putty) 和 C++ 有什么不同?

从外观上看,我假设您的 class 定义如下所示:

class CSerialPort {
public:
    bool OpenPort(CString portname);
    bool WriteByte(const char* bybyte);

private:
    HANDLE m_hComm;
    byte m_iBytesWritten;
};
  • byte不是正确的类型。 DWORD是。
  • 可以使用CString ,但无论如何您都在使用宽字符串文字,因此您可以只使用CreateFileWstd::wstring s 和std::wstring_view s。
  • WriteByte意味着您只想写入一个字节——事实上,您的实现只写入一个字节——但它是错误的字节。 它从bybyte变量的 memory 中写入一个字节,而不是它指向的 memory。

class 的一个小的重新定义:

#include <string_view> // added header

class CSerialPort {
public:
    // take a `std::wstring` instead
    bool OpenPort(const std::wstring& portname);

    // WriteBytes instead of WriteByte:
    bool WriteBytes(const void* bytesPtr, DWORD bytesToWrite);

    // write both wide and non-wide string_views    
    bool WriteString(std::string_view str);
    bool WriteString(std::wstring_view str);

private:
    HANDLE m_hComm;
    DWORD m_iBytesWritten; // the proper type
};

.cpp文件中的实现变为:

bool CSerialPort::OpenPort(const std::wstring& portname) {
    // Use CreateFileW since you've hardcoded wide string literals anyway:
    m_hComm = CreateFileW((L"//./" + portname).c_str(),
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        0,
        0);
    return m_hComm != INVALID_HANDLE_VALUE;
}

bool CSerialPort::WriteBytes(const void* bytesPtr, DWORD bytesToWrite)
{
    return
        WriteFile(m_hComm, bytesPtr, bytesToWrite, &m_iBytesWritten, nullptr) != 0;
}

// the WriteString overloads taking string_views pass on the pointer
// and length to `WriteBytes`:
bool CSerialPort::WriteString(std::string_view str) {
    return WriteBytes(str.data(), str.size());
}

bool CSerialPort::WriteString(std::wstring_view str) {
    return WriteBytes(str.data(), str.size() * // wchar_t's are more than 1 byte:
                                  sizeof(std::wstring_view::value_type));
}

然后您的main将使用WriteString重载获取std::string_view (通过将const char*传递给WriteString ):

int main()
{
    CSerialPort _serial;

    if(_serial.OpenPort(L"COM4")) {
        _serial.WriteString("km.press('a')");
    } else {
        std::cerr << "failed opening COM4\n";
    }
}

注意:您在最后添加的部分有几个错误:

string test = "km.move(0,1)";
DWORD dwBytesWritten;
WriteFile(m_hComm,&test,sizeof(test),dwBytesWritten,NULL);
  • &test获取std::string的地址 object。您应该使用test.c_str()获取字符串中第一个字符的const char*
  • sizeof(test)获取std::string object 的大小,而不是实际字符串的长度。 您应该改用test.size()
  • dwBytesWritten按值传递,但 function 需要一个指向它可以写入的DWORD的指针。 您应该改用&dwBytesWritten
WriteFile(m_hComm, test.c_str(), test.size(), &dwBytesWritten, NULL);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM