C++ 不占用串口,用钩子监听串口信息的demo
时间: 2024-03-13 13:45:43 浏览: 207
以下是一个使用钩子监听串口信息的 C++ 示例代码:
```cpp
#include <iostream>
#include <Windows.h>
// 串口号
const int COM_PORT_NUMBER = 5;
// 钩子回调函数
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
// 获取串口数据
if (wParam == 0x100)
{
CHAR c = *((CHAR*)lParam);
std::cout << c;
}
}
// 继续下一个钩子
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int main()
{
// 打开串口
HANDLE hCom = CreateFileA(("COM" + std::to_string(COM_PORT_NUMBER)).c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if (hCom == INVALID_HANDLE_VALUE)
{
std::cerr << "Failed to open COM port" << std::endl;
return 1;
}
// 配置串口参数
DCB dcb = { 0 };
dcb.DCBlength = sizeof(DCB);
if (!GetCommState(hCom, &dcb))
{
std::cerr << "Failed to get COM port state" << std::endl;
CloseHandle(hCom);
return 1;
}
dcb.BaudRate = CBR_9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(hCom, &dcb))
{
std::cerr << "Failed to set COM port state" << std::endl;
CloseHandle(hCom);
return 1;
}
// 创建钩子
HHOOK hHook = SetWindowsHookEx(WH_GETMESSAGE, HookProc, NULL, GetCurrentThreadId());
if (hHook == NULL)
{
std::cerr << "Failed to create hook" << std::endl;
CloseHandle(hCom);
return 1;
}
// 监听串口数据
OVERLAPPED ov = { 0 };
ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (ov.hEvent == NULL)
{
std::cerr << "Failed to create overlapped event" << std::endl;
UnhookWindowsHookEx(hHook);
CloseHandle(hCom);
return 1;
}
CHAR buf[1024];
DWORD dwBytesRead;
while (ReadFile(hCom, buf, sizeof(buf), &dwBytesRead, &ov))
{
// 等待串口数据
WaitForSingleObject(ov.hEvent, INFINITE);
// 重置事件
ResetEvent(ov.hEvent);
// 继续监听
ov.Offset += dwBytesRead;
ov.OffsetHigh = 0;
}
// 清理资源
CloseHandle(ov.hEvent);
UnhookWindowsHookEx(hHook);
CloseHandle(hCom);
return 0;
}
```
这个示例代码中,我们使用 `CreateFile` 打开串口,使用 `GetCommState` 和 `SetCommState` 配置串口参数,使用 `ReadFile` 和 `OVERLAPPED` 监听串口数据。同时,我们使用 `SetWindowsHookEx` 创建一个钩子,使用 `WH_GETMESSAGE` 监听 Windows 消息,并在钩子回调函数中打印串口数据。注意,我们使用 `CallNextHookEx` 继续下一个钩子,以确保不影响其他程序的正常运行。
另外,由于串口数据可能较多,我们使用 `OVERLAPPED` 配合 `ReadFile` 实现异步读取,并使用事件对象等待读取完成。
阅读全文