菜单

ACP C++使用手册

概述

本手册使用一台SX21作为ACP服务器,Ubuntu电脑作为客户端来读取、写入和订阅PLC变量功能。如下图所示:

下表概述了本手册各个产品组件

产品组件 描述说明
DeviceManager_0.0.1.9 工智机插件安装管理器
acpsymbollib_1.0.1_amd64.deb Ubuntu客户端deb组件
libacp_0.2.3_amd64.deb acpsymbollib依赖文件
CppAcpServer.projectarchive PLC工程存档
AcpClient.cpp Linux客户端C++示例程序

安装卸载

安装要求

  • 中科时代出厂的工智机的自带系统;
  • 工智机可以访问互联网;
  • Ubuntu系统客户端可以访问互联网;

安装过程

1、工智机安装acpplcaccess.deb组件

1.打开Device Manager软件,使用工智机固定网口与个人电脑通讯。

2.初次使用,需要安装ACP通讯服务。点击左下角“安装ACP服务”。

3.输入工智机固定IP地址、端口、用户名和密码后,点击“在线安装”。

IP地址 192.168.1.200
端口 2224
用户名 sinsegye
密码 1

等待安装完成。

4.安装完成后,点击“扫描”,即可扫描出固定网口192.168.1.200连接的工智机。

点击进入工智机后,左下角显示“已连接”状态。

5.点击“安装RTE插件服务”

6.输入用户名:sinsegye,密码:1,点击“在线安装”

7.安装完成后,点击“软件”,在下拉菜单下选择“组件管理”

8.点击浏览,可以在线浏览可以安装的组件。

9.在组件中找到“SF1000-acpplcaccess”--点击“安装”

10.等待deb包传送到工智机中,传送完成后点击“确定”进行安装。

11.安装完成后,点击“确认”重启生效。

12.安装完成后,可以在“本地”页面浏览到SF1000-acpplcaccess已安装成功。

2、Ubuntu 20.04电脑安装acpsymbollib和libacp库文件

将官网下载的acpsymbollib_1.0.1_amd64.deb文件和libacp_0.2.3_amd64.deb文件拷贝到Ubuntu客户端/home文件夹下。

打开Ubuntu终端,安装acpsymbollib_1.0.1_amd64.deb

shell 复制代码
sudo dpkg -i acpsymbollib\_1.0.1\_amd64.deb

安装libacp_0.2.3_amd64.deb

shell 复制代码
sudo dpkg -i libacp\_0.2.3\_amd64.deb

3、Ubuntu安装VScode

使用Ubuntu Sofeware 安装VScode。没有Ubuntu-soft先使用命令下载。

shell 复制代码
sudo apt-get update
sudo apt -y install ubuntu-software

打开VScode,点击“Extensions”。

搜索“chinese”—— 选择中文(简体)—— 安装

搜索“C++”——点击安装

重启Ubuntu系统。

、设置VScode C++编译环境

Ubuntu打开VScode软件,点击“选择我的默认编辑器”

选择使用g++编译器

点击“打开文件夹”

新建一个文件夹

点击“OPEN”

点击“信任作者”

新建一个cpp文件

编写测试程序

shell 复制代码
#include\<iostream>
using namespace std;
int main(void)
{
cout<<"Hello"<\<endl;
return 0;
} 

点击“终端”——“配置默认生成任务”

选择“g++生成活动文件”

添加“-lacpsymbollib”和“-lacpsymbolapi-c”

点击“运行生成任务”

点击“运行”——“添加配置”

选择“C++”

点击“添加配置”——“(gdb)启动”

修改“program”参数为"{fileDirname}/{fileBasenameNoExtension}"

同时,添加属性“preLaunchTask”:“C/C++: g++ 生成活动文件”

选择Hello.cpp文件——调试,可以在终端看到调试结果。

更新安装

1.ACP服务器更新acpplcaccess组件

在插件管理器Device Mananger--组件管理--本地组件中,点击SF1000-acpplcaccess,选择可更新的版本后,点击“更新”。

2.Linux系统更新acpsymbollib和libacp库文件

从中科时代官网下载最新的acpsymbollib和libacp库文件,使用dpkg -i 重新安装

shell 复制代码
sudo dpkg -i acpsymbollib\_1.0.1\_amd64.deb&#xA;sudo dpkg -i libacp\_0.2.3\_amd64.deb 

卸载过程

1. ACP服务器卸载acpplcaccess组件

在插件管理器Device Mananger--组件管理--本地组件中,点击SF1000-acpplcaccess,选择“卸载”

点击“确定”

卸载成功后,点击“确定”重启生效。

卸载成功后,“本地”页面组件消失。

2、卸载Ubuntu客户端acpsymbollib和libacp库文件

使用dpkg -r命令进行卸载

shell 复制代码
sudo dpkg -r acpsymbollib&#xA;sudo dpkg -r libacp

重启

shell 复制代码
sudo reboot 

3、Ubuntu客户端卸载VScode

使用Ubuntu-Software卸载VScode


技术说明

快速启动

(一)本例软、硬件配置

硬件: 软件
工智机SX21 插件管理器DeviceManager_0.0.1.9
Ubuntu 20.04系统客户端 客户端组件acpsymbollib_1.0.1_amd64.deb
个人电脑 依赖库文件libacp_0.2.3_amd64.deb
服务端PLC工程存档CppAcpServer.projectarchive
客户端C++测试程序AcpClient.cpp
中科时代IDE MetaFacture V1.0.6.6

(二)本例实验操作步骤

1.实验要求

a.工智机使用插件管理器成功安装acpplcaccess组件;

b.Linux系统客户端安装acpsymbollib和liblibacp库文件;

c.Linux系统客户端安装VScode软件,并配置C++编译环境。

2.实验原理图

3.实验步骤

3.1 解压官网下载的工程存档文件“CppAcpServer.projectarchive”,登录工智机,下载运行程序。

3.2 将官网下载的C++程序“AcpClient.cpp”拷贝到Ubuntu的Project文件夹中

3.3 在VScode中选择AcpClient.cpp程序,在main()函数中取消ReadSymbol()注释

修改程序ReadSymbol()中的工智机IP地址:

3.4 点击Debug,读取PLC_PRG程序中的变量

修改程序WriteSymbol()中的工智机IP地址:

3.5 在main()函数中注释ReadSymbol(),取消Writesymbol()注释。点击Debug,写入变量值。

查看工智机的PLC变量值,写入成功。

3.6 在main()函数中注释Writesymbol(),取消SubSymbol()注释。点击Debug,订阅变量。

修改程序SubSymbol()中的工智机IP地址:

订阅的变量数值不断在变化。


示例

读取变量

通过实例化的connParam结构传递TCP连接参数和IP地址,使用AcpCreatConnHandler获得连接句柄。
创建读取变量结构体,设定变量类型,读取路径和读取字符大小,使用AcpReadTagList进行读取。

详细参数说明见功能介绍

shell 复制代码
void ReadSymbol()
{
  ConnParam connParam;
  connParam.connType = AcpConnType::ACP_CONN_TYPE_TCP;
  const char* ipAddress = "192.168.110.114";
  strncpy(connParam.szConnParam, ipAddress, sizeof(connParam.szConnParam) - 1);
  connParam.szConnParam[sizeof(connParam.szConnParam) - 1] = '\0';  // 确保以 null 结尾

  auto handle = AcpCreatConnHandler(&connParam);

    TagInfo readinfo[15];

    ST_BOOL bool1_ = false;
    std::string strBoolPath = "Application.PLC_PRG.xVar1";

    ST_BYTE byte1_ = 0;
    std::string strBytePath = "Application.PLC_PRG.bVar2";

    ST_WORD word1_=0;
    std::string strWordPath = "Application.PLC_PRG.wVar3";

    ST_DWORD dword1_=0;
    std::string strDwordPath = "Application.PLC_PRG.dwVar4";

    ST_LWORD lword1_=0;
    std::string strLwordPath = "Application.PLC_PRG.lwVar5";

    ST_SINT sint1_=0;
    std::string strSintPath = "Application.PLC_PRG.siVar6";

    ST_USINT usint1_=0;
    std::string strUsintPath = "Application.PLC_PRG.usiVar7";

    ST_INT int1_=0;
    std::string strIntPath = "Application.PLC_PRG.iVar8";

    ST_UINT uint1_=0;
    std::string strUintPath = "Application.PLC_PRG.uiVar9";

    ST_DINT dint1_=0;
    std::string strDintPath = "Application.PLC_PRG.diVar10";

    ST_UDINT udint1_=0;
    std::string strUdintPath = "Application.PLC_PRG.udiVar11";

    ST_LINT lint1_=0;
    std::string strLintPath = "Application.PLC_PRG.liVar12";

    ST_REAL real1_=0;
    std::string strRealPath = "Application.PLC_PRG.rVar13";

    ST_LREAL lreal1_=0;
    std::string strLrealPath = "Application.PLC_PRG.lrVar14";

    ST_STRING str[81];
    std::string strStringPath = "Application.PLC_PRG.sVar15";

    readinfo[0].tagDesc.szSymbolFullName = strBoolPath.c_str();
    readinfo[0].tagValue.pValueData = &bool1_;
    readinfo[0].tagValue.nValueSize = sizeof(ST_BOOL);

    readinfo[1].tagDesc.szSymbolFullName = strBytePath.c_str();
    readinfo[1].tagValue.pValueData = &byte1_;
    readinfo[1].tagValue.nValueSize = sizeof(ST_BYTE);

    readinfo[2].tagDesc.szSymbolFullName = strWordPath.c_str();
    readinfo[2].tagValue.pValueData = &word1_;
    readinfo[2].tagValue.nValueSize = sizeof(ST_WORD);

    readinfo[3].tagDesc.szSymbolFullName = strDwordPath.c_str();
    readinfo[3].tagValue.pValueData = &dword1_;
    readinfo[3].tagValue.nValueSize = sizeof(ST_DWORD);

    readinfo[4].tagDesc.szSymbolFullName = strLwordPath.c_str();
    readinfo[4].tagValue.pValueData = &lword1_;
    readinfo[4].tagValue.nValueSize = sizeof(ST_LWORD);

    readinfo[5].tagDesc.szSymbolFullName = strSintPath.c_str();
    readinfo[5].tagValue.pValueData = &sint1_;
    readinfo[5].tagValue.nValueSize = sizeof(ST_SINT);

    readinfo[6].tagDesc.szSymbolFullName = strUsintPath.c_str();
    readinfo[6].tagValue.pValueData = &usint1_;
    readinfo[6].tagValue.nValueSize = sizeof(ST_USINT);

    readinfo[7].tagDesc.szSymbolFullName = strIntPath.c_str();
    readinfo[7].tagValue.pValueData = &int1_;
    readinfo[7].tagValue.nValueSize = sizeof(ST_INT);

    readinfo[8].tagDesc.szSymbolFullName = strUintPath.c_str();
    readinfo[8].tagValue.pValueData = &uint1_;
    readinfo[8].tagValue.nValueSize = sizeof(ST_UINT);

    readinfo[9].tagDesc.szSymbolFullName = strDintPath.c_str();
    readinfo[9].tagValue.pValueData = &dint1_;
    readinfo[9].tagValue.nValueSize = sizeof(ST_DINT);

    readinfo[10].tagDesc.szSymbolFullName = strUdintPath.c_str();
    readinfo[10].tagValue.pValueData = &udint1_;
    readinfo[10].tagValue.nValueSize = sizeof(ST_UDINT);

    readinfo[11].tagDesc.szSymbolFullName = strLintPath.c_str();
    readinfo[11].tagValue.pValueData = &lint1_;
    readinfo[11].tagValue.nValueSize = sizeof(ST_LINT);

    readinfo[12].tagDesc.szSymbolFullName = strRealPath.c_str();
    readinfo[12].tagValue.pValueData = &real1_;
    readinfo[12].tagValue.nValueSize = sizeof(ST_REAL);

    readinfo[13].tagDesc.szSymbolFullName = strLrealPath.c_str();
    readinfo[13].tagValue.pValueData = &lreal1_;
    readinfo[13].tagValue.nValueSize = sizeof(ST_LREAL);

    readinfo[14].tagDesc.szSymbolFullName = strStringPath.c_str();
    readinfo[14].tagValue.pValueData = &str;
    readinfo[14].tagValue.nValueSize = sizeof(str);
     
    auto var_size = sizeof(readinfo) / sizeof(TagInfo);
    auto result = AcpReadTagList(handle, &readinfo[0], var_size, 500);

    if (result != false)
    {
      printf("读取变量失败!\n");
    } 
    else 
    {
      printf("读取变量成功!\n");
      printf("xVar1=%d\n",bool1_);
      printf("bVar2=%d\n",byte1_);
      printf("wVar3=%d\n",word1_);
      printf("dwVar4=%u\n",dword1_);
      printf("lwVar5=%ld\n",lword1_);
      printf("siVar6=%d\n",sint1_);
      printf("usiVar7=%d\n",usint1_);
      printf("iVar8=%d\n",int1_);
      printf("uiVar9=%d\n",uint1_);
      printf("diVar10=%d\n",dint1_);
      printf("udiVar11=%u\n",udint1_);
      printf("liVar12=%ld\n",lint1_);
      printf("rVar13=%f\n",real1_);
      printf("lrVar14=%.8lf\n",lreal1_);
      printf("sVar15=%s \n",str);
    }
}

写入变量

通过实例化的connParam结构传递TCP连接参数和IP地址,使用AcpCreatConnHandler获得连接句柄。
创建写入变量结构体,设定变量类型,写入路径和写入字符大小,使用AcpWriteTagList进行读取。

详细参数说明见功能介绍

shell 复制代码
void WriteSymbol()
{
  ConnParam connParam;
  connParam.connType = AcpConnType::ACP_CONN_TYPE_TCP;
  const char* ipAddress = "192.168.110.114";
  strncpy(connParam.szConnParam, ipAddress, sizeof(connParam.szConnParam) - 1);
  connParam.szConnParam[sizeof(connParam.szConnParam) - 1] = '\0';  // 确保以 null 结尾

  auto handle = AcpCreatConnHandler(&connParam);

    TagInfo writeinfo[15];

    ST_BOOL bool1_ = false;
    std::string strBoolPath = "Application.PLC_PRG.xVar1";

    ST_BYTE byte1_ = 27;
    std::string strBytePath = "Application.PLC_PRG.bVar2";

    ST_WORD word1_=55533;
    std::string strWordPath = "Application.PLC_PRG.wVar3";

    ST_DWORD dword1_=4000000000;
    std::string strDwordPath = "Application.PLC_PRG.dwVar4";

    ST_LWORD lword1_=6666666666;
    std::string strLwordPath = "Application.PLC_PRG.lwVar5";

    ST_SINT sint1_=-88;
    std::string strSintPath = "Application.PLC_PRG.siVar6";

    ST_USINT usint1_=222;
    std::string strUsintPath = "Application.PLC_PRG.usiVar7";

    ST_INT int1_=-32666;
    std::string strIntPath = "Application.PLC_PRG.iVar8";

    ST_UINT uint1_=33355;
    std::string strUintPath = "Application.PLC_PRG.uiVar9";

    ST_DINT dint1_=2121212121;
    std::string strDintPath = "Application.PLC_PRG.diVar10";

    ST_UDINT udint1_=3000000000;
    std::string strUdintPath = "Application.PLC_PRG.udiVar11";

    ST_LINT lint1_=8888888888;
    std::string strLintPath = "Application.PLC_PRG.liVar12";

    ST_REAL real1_=543.9876;
    std::string strRealPath = "Application.PLC_PRG.rVar13";

    ST_LREAL lreal1_=678.1234567;
    std::string strLrealPath = "Application.PLC_PRG.lrVar14";

    ST_STRING str[81];
    const char* source = "Sinsegye and sinsegye";
    strcpy(str, source);  // NOLINT
    std::string strStringPath = "Application.PLC_PRG.sVar15";


    writeinfo[0].tagDesc.szSymbolFullName = strBoolPath.c_str();
    writeinfo[0].tagValue.pValueData = &bool1_;
    writeinfo[0].tagValue.nValueSize = sizeof(ST_BOOL);

    writeinfo[1].tagDesc.szSymbolFullName = strBytePath.c_str();
    writeinfo[1].tagValue.pValueData = &byte1_;
    writeinfo[1].tagValue.nValueSize = sizeof(ST_BYTE);

    writeinfo[2].tagDesc.szSymbolFullName = strWordPath.c_str();
    writeinfo[2].tagValue.pValueData = &word1_;
    writeinfo[2].tagValue.nValueSize = sizeof(ST_WORD);

    writeinfo[3].tagDesc.szSymbolFullName = strDwordPath.c_str();
    writeinfo[3].tagValue.pValueData = &dword1_;
    writeinfo[3].tagValue.nValueSize = sizeof(ST_DWORD);

    writeinfo[4].tagDesc.szSymbolFullName = strLwordPath.c_str();
    writeinfo[4].tagValue.pValueData = &lword1_;
    writeinfo[4].tagValue.nValueSize = sizeof(ST_LWORD);

    writeinfo[5].tagDesc.szSymbolFullName = strSintPath.c_str();
    writeinfo[5].tagValue.pValueData = &sint1_;
    writeinfo[5].tagValue.nValueSize = sizeof(ST_SINT);

    writeinfo[6].tagDesc.szSymbolFullName = strUsintPath.c_str();
    writeinfo[6].tagValue.pValueData = &usint1_;
    writeinfo[6].tagValue.nValueSize = sizeof(ST_USINT);

    writeinfo[7].tagDesc.szSymbolFullName = strIntPath.c_str();
    writeinfo[7].tagValue.pValueData = &int1_;
    writeinfo[7].tagValue.nValueSize = sizeof(ST_INT);

    writeinfo[8].tagDesc.szSymbolFullName = strUintPath.c_str();
    writeinfo[8].tagValue.pValueData = &uint1_;
    writeinfo[8].tagValue.nValueSize = sizeof(ST_UINT);

    writeinfo[9].tagDesc.szSymbolFullName = strDintPath.c_str();
    writeinfo[9].tagValue.pValueData = &dint1_;
    writeinfo[9].tagValue.nValueSize = sizeof(ST_DINT);

    writeinfo[10].tagDesc.szSymbolFullName = strUdintPath.c_str();
    writeinfo[10].tagValue.pValueData = &udint1_;
    writeinfo[10].tagValue.nValueSize = sizeof(ST_UDINT);

    writeinfo[11].tagDesc.szSymbolFullName = strLintPath.c_str();
    writeinfo[11].tagValue.pValueData = &lint1_;
    writeinfo[11].tagValue.nValueSize = sizeof(ST_LINT);

    writeinfo[12].tagDesc.szSymbolFullName = strRealPath.c_str();
    writeinfo[12].tagValue.pValueData = &real1_;
    writeinfo[12].tagValue.nValueSize = sizeof(ST_REAL);

    writeinfo[13].tagDesc.szSymbolFullName = strLrealPath.c_str();
    writeinfo[13].tagValue.pValueData = &lreal1_;
    writeinfo[13].tagValue.nValueSize = sizeof(ST_LREAL);

    writeinfo[14].tagDesc.szSymbolFullName = strStringPath.c_str();
    writeinfo[14].tagValue.pValueData = &str;
    writeinfo[14].tagValue.nValueSize = sizeof(str);

    auto var_size = sizeof(writeinfo) / sizeof(TagInfo);
    auto result = AcpWriteTagList(handle, &writeinfo[0], var_size, 500);

     if (result != false) 
     {
      printf("写入变量失败!\n");
     }
     else
     {
      printf("写入变量成功!\n");
     }
}

订阅变量

通过实例化的connParam结构传递TCP连接参数和IP地址,使用AcpCreatConnHandler获得连接句柄。
使用AcpRegisterNotifyCallBack注册回调函数NotifyCallback;
创建订阅变量结构体,设定订阅变量路径,使用AcpAddTagsNotification添加订阅变量列表。

详细参数说明见功能介绍

shell 复制代码
void SubSymbol() {
  ConnParam connParam;
  const char* ipAddress = "192.168.110.114";
  strncpy(connParam.szConnParam, ipAddress, sizeof(connParam.szConnParam) - 1);
  connParam.szConnParam[sizeof(connParam.szConnParam) - 1] = '\0';  // 确保以 null 结尾

  auto handle = AcpCreatConnHandler(&connParam);
  auto result = AcpRegisterNotifyCallBack(handle, NotifyCallback, nullptr);//注册回调函数

  TagInfo symbol[15];
 
  std::string str0 =  "Application.GVL.BOOL1";
  std::string str1 =  "Application.GVL.BYTE2";
  std::string str2 =  "Application.GVL.WORD3";
  std::string str3 =  "Application.GVL.DWORD4";
  std::string str4 =  "Application.GVL.LWORD5";
  std::string str5 =  "Application.GVL.SINT6";
  std::string str6 =  "Application.GVL.USINT7";
  std::string str7 =  "Application.GVL.INT8";
  std::string str8 =  "Application.GVL.UINT9";
  std::string str9 =  "Application.GVL.DINT10";
  std::string str10 = "Application.GVL.UDINT11";
  std::string str11 = "Application.GVL.LINT12";
  std::string str12 = "Application.GVL.REAL13";
  std::string str13 = "Application.GVL.LREAL14";
  std::string str14 = "Application.GVL.STRING15";
  symbol[0].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str0.c_str()));
  symbol[1].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str1.c_str()));
  symbol[2].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str2.c_str()));
  symbol[3].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str3.c_str()));
  symbol[4].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str4.c_str()));
  symbol[5].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str5.c_str()));
  symbol[6].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str6.c_str()));
  symbol[7].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str7.c_str()));
  symbol[8].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str8.c_str()));
  symbol[9].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str9.c_str()));
  symbol[10].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str10.c_str()));
  symbol[11].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str11.c_str()));
  symbol[12].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str12.c_str()));
  symbol[13].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str13.c_str()));
  symbol[14].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str14.c_str()));
  
  auto nameSize = sizeof(symbol) / sizeof(TagInfo);
  
  int reqid = 6;                //订阅ID
  TagSubParam subParam;
  subParam.nIntervalMs = 15;    //订阅间隔时间
  subParam.nRequestId = reqid; //订阅ID
  result = AcpAddTagsNotification(handle, &symbol[0], nameSize, &subParam, 500);//添加订阅
}

回调函数

当订阅变量的值发生改变,进入回调函数。判断返回的变量名,将数值赋给相应的变量。

shell 复制代码
void NotifyCallback(TagSubInfo* pTagSubInfos, void* lpContext) {

ST_BOOL Subbool1=false;
ST_BYTE Subbyte1=0;
ST_WORD Subword1=0;
ST_DWORD Subdword1=0;
ST_LWORD Sublword1=0;
ST_SINT Subsint1=0;
ST_USINT Subusint1=0;
ST_INT Subint1= 0;
ST_UINT Subuint1=0;
ST_DINT Subdint1=0;
ST_UDINT Subudint1=0;
ST_LINT Sublint1=0;
ST_REAL Subreal1= 0;
ST_LREAL Sublreal1=0;
ST_STRING Substring1[80]="";

  if (pTagSubInfos->enReplyType == AcpSubReplyType::subscribefailed) 
  {
    printf("订阅失败! \n");
    if (pTagSubInfos->subFailSize > 0) 
    {
      printf("订阅失败的变量: ");
      for (uint64_t i = 0; i < pTagSubInfos->subFailSize; i++)
      {
        std::string name = std::string(pTagSubInfos->subFailTagsInfo[i].tagDesc.szSymbolFullName);
        printf("%s ", name.c_str());
      }
      printf("\n");
    }
  }
  else if (pTagSubInfos->enReplyType == AcpSubReplyType::subscribedelok) 
  {
    printf("取消订阅成功! \n");
  } 
  else if (pTagSubInfos->enReplyType == AcpSubReplyType::subscribeNotify)
  {
    printf("symbolSubReply->symbolSize:%d\n", pTagSubInfos->subOkSize);
    for (uint64_t i = 0; i < pTagSubInfos->subOkSize; i++) 
    {
      
      auto itemName = std::string(pTagSubInfos->subOkTagsInfo[i].tagDesc.szSymbolFullName);

      if (itemName == "Application.GVL.BOOL1") 
      {
        memcpy(&Subbool1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.BOOL1: %d\n", Subbool1);
      } 
      else if (itemName == "Application.GVL.BYTE2") 
      {
        memcpy(&Subbyte1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.BYTE2: %d\n", Subbyte1);
      }
      else if (itemName == "Application.GVL.WORD3") 
      {
        memcpy(&Subword1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.WORD3: %d\n", Subword1);
      }
      else if (itemName == "Application.GVL.DWORD4") 
      {
        memcpy(&Subdword1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.DWORD4: %u\n", Subdword1);
      }
      else if (itemName == "Application.GVL.LWORD5") 
      {
        memcpy(&Sublword1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.LWORD5: %ld\n", Sublword1);
      }
      else if (itemName == "Application.GVL.SINT6") 
      {
        memcpy(&Subsint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.SINT6: %d\n", Subsint1);
      }
      else if (itemName == "Application.GVL.USINT7") 
      {
        memcpy(&Subusint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.USINT7: %d\n", Subusint1);
      }
      else if (itemName == "Application.GVL.INT8") 
      {
        memcpy(&Subint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.INT8: %d\n", Subint1);
      }
      else if (itemName == "Application.GVL.UINT9") 
      {
        memcpy(&Subuint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.UINT9: %d\n", Subuint1);
      }
      else if (itemName == "Application.GVL.DINT10") 
      {
        memcpy(&Subdint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.DINT10: %d\n", Subdint1);
      }
      else if (itemName == "Application.GVL.UDINT11") 
      {
        memcpy(&Subudint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.UDINT11: %u\n", Subudint1);
      }
      else if (itemName == "Application.GVL.LINT12") 
      {
        memcpy(&Sublint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.LINT12: %ld\n", Sublint1);
      }
      else if (itemName == "Application.GVL.REAL13") 
      {
        memcpy(&Subreal1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.REAL13: %f\n", Subreal1);
      }
      else if (itemName == "Application.GVL.LREAL14") 
      {
        memcpy(&Sublreal1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.LREAL14: %lf\n", Sublreal1);
      }
      else if (itemName == "Application.GVL.STRING15") 
      {
        memcpy(&Substring1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
               pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
        printf("Application.GVL.STRING15: %s\n", Substring1);
      }

    }
  }
}

主函数

取消相应的注释来调用读取变量、写入变量和订阅变量的方法。

C++ 复制代码
int main() {
  //ReadSymbol();//读取变量
  //WriteSymbol();//写入变量
  //SubSymbol();//订阅变量
  while (1) 
  {
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));//暂停1s
  }
  return 0;
}
最近修改: 2025-04-18