You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在自研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, &notification_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 18:23:10