[英]C++ Serial COM Port Access
在 uPyCraft IDE 或 Putty 中,只需发送 km.press('a') 然后它工作正常,但在我的 C++ 中,我尝试使用 km.press('a') 写入文件,它不起作用。 我找不到问题所在
`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
,但无论如何您都在使用宽字符串文字,因此您可以只使用CreateFileW
、 std::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.