如何在自研C++应用中捕获ADSLOGSTR(非仅TwinCAT XAE)
捕获TwinCAT PLC的ADSLOGSTR日志消息
我正在开发一款通过ADS协议与PLC交互的应用。PLC端编写了如下代码,调用ADSLOGSTR输出的日志能在TwinCAT XAE的输出窗口正常显示,但我借助ADS-C++示例实现了变量读写、变更通知功能后,却无法在自研应用中捕获这些日志消息。
PLC代码:
IF bSendMessage THEN ADSLOGSTR( msgCtrlMask := ADSLOG_MSGTYPE_ERROR, msgFmtStr := 'This is an error: %s', strArg := 'Details'); END_IF;
解决方案
通过订阅ADS日志服务端口的设备通知,可捕获ADSLOGSTR输出的消息,完整实现代码如下:
#include <iostream> #include <windows.h> #include <conio.h> // TwinCAT 3 ADS头文件 #include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsDef.h" #include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsAPI.h" int main() { long error(0); // 打开ADS路由器的通信端口 AdsPortOpen(); AmsAddr addr = { { 41, 249, 209, 138, 1, 1 }, // 目标PLC的AMS地址,需根据实际环境修改 AMSPORT_LOGGER // ADS日志服务固定端口 }; try { unsigned long index_group = 1; unsigned long index_offset = 0xffff; AdsNotificationAttrib attr = { .cbLength = 1024, // 设置消息缓冲区长度,适配日志内容大小 .nTransMode = ADSTRANS_SERVERCYCLE, // 采用服务器周期传输模式 .nMaxDelay = 0, // 无最大延迟 .nCycleTime = 0 // 周期时间设为0,实时接收日志 }; // 向ADS日志服务订阅设备通知 unsigned long notification_handle(0); error = AdsSyncAddDeviceNotificationReq( &addr, index_group, index_offset, &attr, [](AmsAddr* addr, AdsNotificationHeader* notification, unsigned long handle) { // 日志消息数据从第16字节开始,提取有效内容并输出 std::string message((char*)(notification->data + 16), notification->cbSampleSize - 16); std::cout << message << std::endl; }, 0, ¬ification_handle); if (error != 0) { throw new std::runtime_error("订阅日志服务失败"); } // 保持程序运行,等待用户按键退出 std::cout << "按任意键退出程序..." << std::endl; _getch(); // 取消日志通知订阅 error = AdsSyncDelDeviceNotificationReq(&addr, notification_handle); if (error != 0) { throw new std::runtime_error("取消日志订阅失败"); } } catch (...) { // 可根据需求添加异常捕获与处理逻辑 } // 关闭ADS通信端口 AdsPortClose(); return 0; }
内容的提问来源于stack exchange,提问作者reinier
相关产品推荐
相关产品推荐

