TwinCAT中传递非特定变量类型指针的问题
解决FB_XmlSrvRead/Write传入DWORD指针报1808(ADSERR_DEVICE_SYMBOLNOTFOUND)错误
错误原因
FB_XmlSrvRead/FB_XmlSrvWrite的pSymAddr参数并非单纯的内存地址数值,它需要的是带符号上下文的指针引用,而非裸DWORD类型的内存地址值。当你用TO_DWORD(ADR())转换地址时,虽然消除了编译错误,但丢失了该地址对应的符号元数据(如变量名、所属符号表、访问权限等)。ADS服务内部需要通过这些元数据查找对应的设备符号,裸DWORD地址无法关联到有效符号条目,因此返回ADSERR_DEVICE_SYMBOLNOTFOUND错误。
正确实现方案
改用POINTER TO BYTE作为通用指针类型,直接传递变量的地址引用,无需转换为DWORD:
示例代码
VAR hXmlSrv: DWORD; // XML服务句柄 pGenericPtr: POINTER TO BYTE; // 通用字节指针,适配任意变量类型 TargetInt: INT; // 测试INT变量 TargetReal: REAL; // 测试REAL变量 dwReadStatus: DWORD; // 读取状态 dwWriteStatus: DWORD; // 写入状态 fbXmlRead: FB_XmlSrvRead; fbXmlWrite: FB_XmlSrvWrite; END_VAR // 读取INT类型变量 pGenericPtr := ADR(TargetInt); dwReadStatus := fbXmlRead.Execute( hXmlSrv := hXmlSrv, pSymAddr := pGenericPtr, dwSize := SIZEOF(TargetInt), // 传入变量实际大小 // 其他必要参数... ); // 写入REAL类型变量 pGenericPtr := ADR(TargetReal); dwWriteStatus := fbXmlWrite.Execute( hXmlSrv := hXmlSrv, pSymAddr := pGenericPtr, dwSize := SIZEOF(TargetReal), // 匹配变量大小 // 其他必要参数... );
关键注意事项
- 匹配变量大小:必须确保
dwSize参数的值与目标变量的实际内存大小一致,用SIZEOF(变量)可准确获取该值,避免内存越界或数据损坏。 - 避免变量优化:编译项目时,确保目标变量未被编译器优化掉(若变量未被直接引用,需在变量属性中设置“保留符号”)。
- 权限与上下文:若跨任务或跨设备访问变量,需确认ADS服务具备对应变量的读写权限,且变量所在的任务/设备处于在线状态。
内容的提问来源于stack exchange,提问作者Richard Cunliffe
相关产品推荐
相关产品推荐

