CODESYS中ANY类型:从类型安全到动态灵活的工业自动化编程实践
1. 项目概述从“类型安全”到“动态灵活”的跨越在工业自动化编程领域尤其是使用像CODESYS这样的主流IEC 61131-3平台时我们长期被“类型安全”这一铁律所塑造。每一个变量都必须预先声明其精确的数据类型——BOOL,INT,REAL,ARRAY[1..10] OF INT或是精心设计的STRUCT。这种强类型系统是程序稳定运行的基石它能在编译阶段就揪出大量潜在错误比如试图把一个字符串赋值给一个整数变量。然而随着项目复杂度的提升尤其是面临需要处理未知格式的数据、构建高度通用的函数库如日志记录、数据序列化或与异构系统如不同厂商的PLC、数据库、Web服务交互时这种严格的类型约束有时会显得束手束脚。你可能会想能不能有一个变量它可以“容纳”任何类型的数据能不能写一个函数它的输入参数在编写时不需要确定具体类型这就是ANY数据类型出现的背景。它不是对类型安全的背叛而是一种在严格框架下开辟的、可控的“动态性”后门。简单来说ANY类型是一个指针它指向一块内存以及描述这块内存中数据“形状”即类型信息的元数据。当你将一个变量声明为ANY时你并不是说它没有类型而是说它的类型在编译时是未知的将在运行时根据实际赋予它的值来确定。这听起来有点像某些高级语言中的Variant或Object但在以实时性和确定性著称的PLC世界里ANY的实现更加底层和高效其行为也受到IEC标准的严格定义。对于从传统PLC编程转向复杂系统集成的工程师来说理解并善用ANY意味着你能设计出前所未有的灵活且强大的功能块。例如一个通用的调试信息打印函数可以接收任何数据类型的变量并格式化成字符串一个数据归档函数可以无需修改代码就记录来自不同工艺段、结构迥异的生产数据包。这不仅仅是语法糖它是一种思维模式的升级让你从“为特定类型写代码”转向“为抽象接口写代码”。2. ANY类型的核心原理与内存模型剖析要安全有效地使用ANY绝不能停留在“它能存放任何东西”的模糊认知上。我们必须深入其内部实现理解它如何在CODESYS的运行时环境中工作。这能从根本上解释许多看似怪异的行为并避免致命错误。2.1 ANY的本质带类型描述的指针在CODESYS中一个ANY类型的变量并不是一个“万能容器”它不直接存储数据本身。实际上它是一个固定大小的数据结构通常包含两个核心部分类型信息指针指向一个描述数据类型的结构体。这个结构体定义了数据的种类基本类型、数组、结构体等、元素类型、数组维度和大小等。数据指针指向实际数据所在的内存地址。当你执行anyVar : intVar;这样的赋值时发生的是浅拷贝。anyVar的类型信息部分被设置为INT的描述数据指针部分则指向intVar的内存地址。这里有一个至关重要的细节ANY并不复制数据本身。这意味着如果你通过ANY指针修改了数据原始变量的值也会改变。这与INT到INT的赋值值拷贝有本质区别。2.2 类型描述符与运行时类型识别CODESYS在背后为每一种出现在程序中的数据类型包括你自定义的STRUCT和FUNCTION_BLOCK都生成一个唯一的类型描述符。当你使用ANY时系统就是通过比对ANY变量所携带的类型描述符来执行运行时检查。例如在调用一个使用ANY输入的函数块时函数块内部代码可以并且应该检查传入的ANY参数是否与期望的类型匹配。IEC 61131-3第三版标准定义了TYPE_OF()和IS_INSTANCE_OF()等运算符用于在ST结构化文本语言中直接进行这种类型查询。虽然CODESYS对这些标准运算符的支持情况需查阅具体版本手册但通过系统库或底层功能实现类型判断是ANY应用的基础。2.3 内存布局示例与风险假设我们有一个结构体和一个ANY变量TYPE ST_Recipe : STRUCT id : INT; name : STRING(255); temperature : REAL; END_STRUCT END_TYPE VAR myRecipe : ST_Recipe : (id : 1, name : ‘Default‘, temperature : 25.5); anyBuffer : ANY; END_VAR执行anyBuffer : ADR(myRecipe);与anyBuffer : myRecipe;是截然不同的。anyBuffer : ADR(myRecipe);anyBuffer的类型信息被设置为POINTER TO ST_Recipe数据指针指向myRecipe变量的地址。你需要通过指针解引用来访问数据这通常需要配合ANY_TO_POINTER转换和明确的类型转换非常底层且危险。anyBuffer : myRecipe;这是更常见和推荐的方式。CODESYS会自动将anyBuffer的类型信息设置为ST_Recipe数据指针指向myRecipe的数据区。你可以使用ANY相关的函数来安全地访问其字段。注意直接操作ANY内部指针是极度危险的行为除非你非常清楚自己在做什么。错误的指针操作可能导致PLC运行时访问非法内存引发“Memory Access Violation”错误这是最高优先级的故障会直接导致PLC进入停止状态。在绝大多数应用场景中我们应该使用CODESYS提供的标准库函数如SysMem库中的函数或安全模式来操作ANY数据。3. ANY类型的实战应用场景与代码实现理解了原理我们来看ANY如何解决实际问题。下面通过几个典型场景展示从声明、赋值到使用的完整流程。3.1 场景一构建通用数据记录与调试功能块这是ANY最经典的应用。我们需要一个FB_GenericLogger它能将任意变量的名称、值和时间戳记录到文件或发送到网络。FUNCTION_BLOCK FB_GenericLogger VAR_INPUT dataName : STRING; dataValue : ANY; // 关键输入参数类型为ANY END_VAR VAR internalBuffer : ARRAY[1..1024] OF BYTE; // 用于临时存储格式化的数据 typeInfo : POINTER TO __SYSTEM.TYPEDESCRIPTION; // 类型信息指针概念性 END_VAR实现步骤获取类型信息在功能块内部首先需要获取传入dataValue的类型描述符。CODESYS可能通过__GET_TYPEID()或类似内部函数提供此功能。我们需要查阅对应版本的运行时库文档。类型判断与格式化使用CASE语句或IF...ELSIF链根据类型信息将数据转换为字符串。例如CASE typeInfo^.typeClass OF __SYSTEM.TYPE_CLASS_INT: stringValue : INT_TO_STRING(ANY_TO_INT(dataValue)); __SYSTEM.TYPE_CLASS_REAL: stringValue : REAL_TO_STRING(ANY_TO_REAL(dataValue)); __SYSTEM.TYPE_CLASS_STRING: stringValue : ANY_TO_STRING(dataValue); // ... 处理其他基本类型和数组 ELSE stringValue : ‘Unsupported Type‘; END_CASE实操心得对于复杂的自定义STRUCT通用的格式化非常困难。一个实用的技巧是要求所有需要通过此记录器记录的结构体都实现一个特定的方法如ToString()然后在ANY处理中通过查询接口或调用预定义的函数指针来调用该方法。这需要更高级的设计模式。拼接与输出将dataName、stringValue和当前时间戳拼接成一行日志写入文件缓冲区。调用示例VAR logger : FB_GenericLogger; cycleCount : INT : 0; motorSpeed : REAL : 1500.0; alarmMessage : STRING : ‘Over temperature‘; END_VAR logger(dataName : ‘CycleCount‘, dataValue : cycleCount); logger(dataName : ‘MotorSpeed‘, dataValue : motorSpeed); logger(dataName : ‘Alarm‘, dataValue : alarmMessage);一个函数块处理了INT、REAL、STRING三种完全不同的数据类型这就是ANY带来的灵活性。3.2 场景二实现可变参数列表的函数虽然IEC 61131-3标准本身不支持像C语言printf那样的可变参数但我们可以利用ANY类型和数组来模拟。创建一个函数块用于将多个任意类型的变量打包成一个字节数组用于网络传输或持久化存储。FUNCTION_BLOCK FB_VariablePacker VAR_INPUT // 使用数组输入每个元素是一个ANY可以接受多个参数 variables : ARRAY[*] OF ANY; END_VAR VAR_OUTPUT buffer : ARRAY[0..1023] OF BYTE; bufferLength : UINT; END_VAR VAR writePos : UINT : 0; i : UINT; END_VAR实现思路遍历ANY数组循环处理variables数组中的每一个元素。写入类型头在buffer中首先写入该变量的类型标识符一个预定义的枚举值和数据的字节长度。拷贝数据根据ANY变量携带的类型信息和数据指针使用MEMCPY函数将实际数据字节拷贝到buffer的相应位置。移动写指针更新writePos指向buffer中的下一个空闲位置。解包时需要另一个功能块FB_VariableUnpacker按照相同的格式类型头数据从buffer中读取并根据类型标识符将数据还原到对应类型的变量中。注意事项这种手动序列化/反序列化非常繁琐且容易出错尤其是处理包含指针的类型如STRING或嵌套结构时。在工业场景中更常见的做法是使用标准的序列化格式如JSON或Google的Protocol Buffers并寻找或开发对应的CODESYS库。ANY在这里的作用是为这些库的通用接口提供可能性。3.3 场景三与高级语言或外部系统的接口当CODESYS需要通过OPC UA、MQTT或自定义TCP/IP协议与MES、SCADA或云平台通信时经常需要处理动态的、模式不固定的数据点。例如一个云平台下发的配方可能包含新的、PLC程序编译时未知的字段。在这种情况下可以在PLC内部定义一个通用的“键值对”结构数组TYPE ST_KeyValuePair : STRUCT key : STRING(50); valueType : INT; // 自定义枚举1INT, 2REAL, 3STRING等 valueData : ARRAY[1..100] OF BYTE; // 存储值的原始字节 // 或者使用ANY但需注意生命周期管理 // valueAny : ANY; END_STRUCT END_TYPE VAR dynamicData : ARRAY[1..50] OF ST_KeyValuePair; END_VAR外部系统将数据解析后根据valueType将值写入valueData字节数组。PLC程序在读取时再根据valueType将字节数组解释为对应的类型。这里ANY可以作为valueData的一种高级替代让内部处理更直接但必须确保ANY指针在整个生命周期内有效即指向的数据未被覆盖或释放。4. 深入ANY的高级特性与边界探索掌握了基础应用后我们来看看ANY的一些高级特性和需要警惕的边界情况。4.1 ANY与引用类型、值类型的交互这是理解ANY行为的关键。在CODESYS中基本类型BOOL,INT,REAL,BYTE等是值类型。anyVar : intVar;之后anyVar指向intVar的存储位置。修改anyVar指向的值就是修改intVar。字符串STRING是特殊的引用类型。一个STRING变量本身是一个固定大小的字符缓冲区描述符。anyVar : stringVar;后anyVar指向这个描述符。对ANY进行字符串操作会影响原stringVar。数组和结构体通常是值类型除非显式使用REFERENCE TO。对于大型数组或结构体赋值给ANY不会产生数据拷贝性能很高但同样意味着修改是“原位”的。示例引用陷阱VAR a : INT : 10; b : INT : 20; anyA, anyB : ANY; END_VAR anyA : a; anyB : anyA; // 将anyB也指向a anyB : b; // 现在anyB指向b了但anyA仍然指向a // 此时通过anyA修改值会影响a通过anyB修改值会影响b两者独立。ANY的赋值是改变其指向而不是拷贝其指向的数据。4.2 使用系统库函数安全操作ANY为了避免直接操作指针的风险应优先使用CODESYS系统库。例如SysMem库可能提供以下函数SysMemGetAnySize获取ANY变量指向的数据所占用的字节数。SysMemCopyAnyToBuffer将ANY指向的数据安全地拷贝到指定的字节数组缓冲区。SysMemCopyBufferToAny将字节数组缓冲区的数据安全地拷贝到ANY指向的位置。这些函数内部会进行边界检查和类型验证比手动进行指针运算安全得多。4.3 ANY的局限性性能开销虽然不拷贝数据但每次使用ANY都涉及额外的间接寻址和运行时类型检查其开销比直接操作强类型变量大。在对实时性要求极高的循环如1ms任务中需谨慎评估。调试困难在线监视时一个ANY类型的变量通常只会显示其内存地址或简单的类型描述无法直接看到其指向的具体值给调试带来不便。丧失编译时检查这是最大的代价。所有类型相关的错误都推迟到了运行时。一个本应在编译期发现的类型不匹配错误现在可能导致运行时功能块内部出错甚至PLC停机。平台兼容性ANY类型的具体内存布局、类型描述符结构以及相关支持函数可能在不同版本的CODESYS运行时或不同厂商的PLC基于CODESYS内核之间存在细微差异。编写高度依赖ANY内部机制的便携式库是困难的。5. 常见问题、调试技巧与最佳实践实录在实际项目中应用ANY我踩过不少坑也总结出一些让代码更健壮的方法。5.1 问题排查速查表问题现象可能原因排查步骤与解决方案PLC运行时访问冲突Memory Access Violation1.ANY指针已失效指向的变量已离开作用域。2. 通过ANY误写了只读内存区。3. 手动指针计算错误访问了非法地址。1.确保生命周期绝对不要将局部变量在函数或功能块内声明的临时变量的地址赋给全局或持久化的ANY变量。局部变量在调用结束后其内存可能被重用。2.使用系统库放弃手动MEMCPY或指针运算改用SysMem等安全函数。3.在线调试使用CODESYS的在线视图检查ANY变量的类型描述信息是否合理。功能块内部处理ANY数据时得到错误值1. 类型判断逻辑有误用处理INT的方式处理了REAL数据。2.ANY指向的数据在外部被意外修改。3. 字节序Endianness问题尤其在跨平台通信时。1.增强类型检查在功能块入口用更详尽的条件判断ANY的实际类型对不支持的类型立即返回错误。2.添加日志在处理前将ANY的类型信息和数据快照通过安全拷贝记录到日志便于回溯。3.明确约定在跨系统接口中明确约定数据格式和字节序。使用ANY的功能块性能低下在高速循环中频繁进行复杂的ANY类型判断和数据处理。1.性能分析使用CODESYS Profiler工具定位热点。2.缓存优化对于循环内不变的ANY参数可在功能块首次调用时识别其类型并缓存处理路径避免每次调用都进行完整判断。3.考虑替代方案对于性能瓶颈处是否能用多个针对特定类型的、重载的功能块来代替单个通用功能块在线监视时ANY变量显示为乱码或奇怪地址监视器无法解析ANY指向的未知或复杂类型。1.自定义监视视图为你的自定义结构体编写__WATCH视图这样当ANY指向该结构体时监视器可以正确显示其字段。2.辅助变量在调试时可以创建临时强类型变量通过安全转换将ANY的值赋给它然后监视这个临时变量。5.2 最佳实践与心得最小化使用范围不要因为“酷”而滥用ANY。将其严格限制在确实需要动态类型的模块如通用日志、通信适配层、配置加载器。业务逻辑核心部分应保持强类型。设计防御性接口任何接受ANY输入的功能块必须在最开始进行严格的类型验证。如果类型不符合预期应立即设置错误输出并返回避免后续操作导致不可预知的行为。提供类型安全的包装器为你强大的通用功能块基于ANY创建一系列针对常用类型的包装函数块。例如为FB_GenericLogger提供LogInt,LogReal,LogString等包装内部只是调用通用块。这样项目中的大多数代码依然享受编译时类型检查只有底层通用块处理ANY。详细文档与注释任何使用ANY的代码都必须附上详尽的注释说明其期望的数据格式、内存所有权谁负责分配和释放以及潜在的限制。这对团队协作和后期维护至关重要。充分的单元测试由于编译时检查减弱对使用ANY的代码进行全面的、覆盖各种数据类型和边缘情况的单元测试是必不可少的。CODESYS的测试管理器Test Manager是完成这项工作的好帮手。ANY类型是CODESYS赋予高级开发者的一把利器它打破了强类型的部分壁垒为实现高度灵活和可复用的代码组件提供了可能。然而正如所有强大的工具一样它需要使用者对其原理有深刻理解并遵循严格的使用规范。将它用在合适的场景并辅以周密的防御性编程和测试你就能在保持PLC程序固有可靠性的同时极大地提升其适应复杂性和变化的能力。从我个人的经验来看成功应用ANY的关键不在于写出最“聪明”的代码而在于构建最“健壮”和“清晰”的抽象。

相关新闻

率零和嘎嘎降AI哪个划算?1万字论文实测:价格/达标率/用时全对比

率零和嘎嘎降AI哪个划算?1万字论文实测:价格/达标率/用时全对比

率零和嘎嘎降AI哪个划算?1万字论文实测:价格/达标率/用时全对比 这两款工具经常被一起比较,因为都是国内降AI工具里知名度比较高的。实际用下来差异不小。这篇文章用同一篇1万字论文分别测了两款,把结果整理出来。 基本参数对比…

2026/8/6 16:00:39 阅读更多 →
每日热门skill-35万次下载!这款Skill让AI Agent装上“自省基因“,从此告别重复犯错

每日热门skill-35万次下载!这款Skill让AI Agent装上“自省基因“,从此告别重复犯错

今日主角:self-improving(ivangdavila) 标签:#AI Agent #自我进化 #记忆管理 #零依赖 一、当AI Agent开始"认错" 想象一个场景。 周一,你让AI Agent帮你把三个季度的销售表合并,跑出环比增长图…

2026/8/6 15:59:38 阅读更多 →
D2DX暗黑破坏神2高清补丁:三分钟让经典游戏焕发第二春

D2DX暗黑破坏神2高清补丁:三分钟让经典游戏焕发第二春

D2DX暗黑破坏神2高清补丁:三分钟让经典游戏焕发第二春 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 还在忍受暗…

2026/8/6 15:59:38 阅读更多 →

最新新闻

跨境厨房清洁用品营销策略:三层漏斗模型解析

跨境厨房清洁用品营销策略:三层漏斗模型解析

1. 项目背景与市场洞察最近两年跨境厨房清洁用品赛道出现了一个有趣的现象:传统铺货模式ROI持续走低,而通过海外社交媒体内容营销的品牌却逆势增长。我在操盘多个家居类目出海项目时发现,单纯依赖头部KOL的"大爆款"策略已经失效&am…

2026/8/6 16:51:07 阅读更多 →
如何3分钟获取中小学电子课本?这款智能教材下载工具为您解决下载难题

如何3分钟获取中小学电子课本?这款智能教材下载工具为您解决下载难题

如何3分钟获取中小学电子课本?这款智能教材下载工具为您解决下载难题 【免费下载链接】tchMaterial-parser 国家中小学智慧教育平台 电子课本下载工具,帮助您从智慧教育平台中获取电子课本的 PDF 文件网址并进行下载,让您更方便地获取课本内容…

2026/8/6 16:51:07 阅读更多 →
2024阀门网站建设指南:如何通过专业的阀门网站建设打造行业爆款

2024阀门网站建设指南:如何通过专业的阀门网站建设打造行业爆款

说句实在话,在这个互联网流量红海都快变成蓝海的今天,如果你还在问“阀门网站建设到底有没有用”,那我可能得先请你喝杯茶,咱俩坐下来好好聊聊。我是真心想帮那些做阀门生意的老板们一把,因为我知道,这一行太难了。以前咱们靠关系、靠饭局、靠跑客户,现在不行了,客户还…

2026/8/6 16:51:07 阅读更多 →
G-Helper终极指南:释放华硕笔记本潜能的免费轻量控制神器

G-Helper终极指南:释放华硕笔记本潜能的免费轻量控制神器

G-Helper终极指南:释放华硕笔记本潜能的免费轻量控制神器 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook,…

2026/8/6 16:51:07 阅读更多 →
Julia实现MIT 18.06 线代计算器

Julia实现MIT 18.06 线代计算器

最近又遇到一个跟DeepSeek较劲半天的代码,DS写julia实在费劲,我又是新学的jl连变量都看不懂,就先把目前好不容易搞出来的MCP线代计算器复盘写篇文章留档。目前支持的是MIT 18.06 线代 Linear Algebra 1-3章节的消元-解方程-逆矩阵。 大背景是…

2026/8/6 16:51:07 阅读更多 →
Unity项目YooAsset缓存清理全攻略:提升开发效率与构建稳定性

Unity项目YooAsset缓存清理全攻略:提升开发效率与构建稳定性

1. 项目概述:为什么Unity项目需要清理YooAsset缓存?做Unity项目开发,尤其是涉及到热更新和资源管理的项目,YooAsset几乎是绕不开的一个强大工具。它帮我们解决了资源打包、加载、更新等一系列繁琐问题,但用久了&#x…

2026/8/6 16:50:07 阅读更多 →

日新闻

深入解析LimboAI C++内核:架构设计与性能优化实战

深入解析LimboAI C++内核:架构设计与性能优化实战

1. 项目概述:为什么我们需要深入LimboAI的C内核?如果你是一名使用Godot引擎的游戏开发者,尤其是对AI行为逻辑有较高要求的项目,那么LimboAI这个名字你大概率不会陌生。它作为Godot 4生态中一个备受瞩目的行为树与状态机插件&#…

2026/8/6 0:00:06 阅读更多 →
Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

1. 项目概述与核心思路大家好,我是老张,一个在游戏开发一线摸爬滚打了十多年的老码农。今天咱们接着聊《空洞骑士》风格2D动作游戏的Demo制作。上一期我们搭好了基础框架,处理了角色移动和碰撞,这一期,我们要让游戏世界…

2026/8/6 0:00:06 阅读更多 →
被动防火门市场前景发展趋势

被动防火门市场前景发展趋势

被动防火门依靠材质结构、密闭构造阻隔烟火蔓延,无需电控启动,是建筑被动消防系统核心构件,行业依托新规管控、城市更新、工业安全升级迎来稳定扩容,整体朝着合规化、专项化、低碳化、智能化方向发展。现阶段 GB12955‑2024 新版国…

2026/8/6 0:00:06 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/5 15:00:43 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/5 13:13:56 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/5 10:20:36 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/5 23:28:39 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/5 21:00:14 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/5 23:46:51 阅读更多 →