尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
gSOAP与ONVIF对接指南:从WSDL到C代码生成的完整实践
简介面向Linux环境下基于ONVIF协议开发网络视频设备的工程师这份编译好的C代码框架由gSOAP工具链生成用于快速搭建与ONVIF设备交互的客户端程序解决手动编写SOAP/XML消息的繁琐问题。压缩包共12个文件包含5个C源文件、5个头文件、1个nsmap命名空间映射文件以及1个Makefile构建脚本整体约1.31MB。其中C源文件与头文件分别为由WSDL自动生成的客户端接口和序列化辅助代码nsmap文件负责XML命名空间绑定Makefile支持一键编译。借助这些文件开发者可直接调用设备发现、GetDeviceInformation、GetStreamUri等ONVIF服务方法获取设备基本信息与RTSP拉流地址还能利用gSOAP内建的错误处理机制排查通信异常。目前已有1687人学习/下载适合具备C语言与Web Service基础、希望快速掌握LinuxgSOAPONVIF开发路径的工程师参考复用。1. 从 ONVIF 接口对接到 gSOAP 生成的 C 代码第一步怎么做搞 ONVIF 对接的 C 工程基本绕不开 gSOAP 这一套工具链。它做的事情很具体把设备管理、媒体、PTZ 等一堆 WSDL 描述直接变成能编译的 C 头文件和客户端/服务端骨架省掉手写 SOAP 编解码、序列化和命名空间管理的体力活。我最早接触它是在某个芯片方案的模拟项目X里做 IPC 接入最开始自己拼 XML 消息包遇到设备不认就反复调接口。后来换成 gSOAP 生成框架整个流程从一个星期压到两天。这篇笔记写给两类人一类是刚接触 ONVIF 的嵌入式开发另一类是手头已有设备端代码、想快速补一套标准接口对接的工程师。先把原理说透再给完整命令和踩坑记录。2. 理解 gSOAP 和 ONVIF 的匹配关系SOAP 骨架到底给你省了什么先讲道理再动手。多数人卡住不是因为命令记不住而是不理解为什么要跑两条命令以及生成出来的到底是一堆什么文件。下面把 ONVIF 的接口模型、gSOAP 的两步生成逻辑以及环境准备说清楚这些搞明白了再进第三章的命令环节会顺手很多。2.1 ONVIF 的接口本质SOAP 消息加标准功能点ONVIF 规范把设备对外能力切成几个功能点设备发现、设备管理、媒体配置、云台控制、事件告警、录像回放。每个功能点对应一组操作比如设备管理里有 GetDeviceInformation、GetSystemDateAndTime、SetHostname媒体服务里有 GetProfiles、GetStreamUriPTZ 里有 ContinuousMove、AbsoluteMove。每个操作都是一对 SOAP 消息请求和响应。SOAP 消息说白了是一份带信封结构的 XML外层有 Envelope、Header、Body里面再塞具体的业务 XML。C 语言没有内建 SOAP 栈通用 XML 库只能帮你生成或解析 XML 树但协议层的命名空间、版本协商、错误处理、Action 绑定全要自己写。真按这个路子做一个 GetProfiles 就得写两百行样板代码后面每接一个设备还要根据响应差异改解析逻辑非常罗兰。gSOAP 把“操作、结构体、XML 报文”三者之间的转换关系固定下来。比如某个_tds__GetDeviceInformation请求结构体序列化之后就是一段符合 ONVIF 规范的 SOAP XML从设备收到的 XML 也能自动反序列化回结构体。这样业务代码里几乎看不到 XML 字符串字段类型由编译器检查排查问题只要看结构体内容就行。2.2 gSOAP 两步生成wsdl2h 与 soapcpp2 各自的活gSOAP 拆成两个工具来用。第一个是wsdl2h它的输入是 WSDL 文件输出是一个 C 头文件。WSDL 里描述的消息类型和端口操作会被翻译成struct定义与函数原型。第二个是soapcpp2它的输入正是这个头文件输出是一整套可编译的 C 源码序列化函数、反序列化函数、客户端调用函数、服务端分发框架还有运行时需要的头文件。整个流程可以理解成两条流水线WSDL 文件 → wsdl2h → onvif.h接口定义 → soapcpp2 → soapClient.c / soapServer.c / soapC.c / soapH.h第一次接触时容易犯的错是直接拿别人仓库里的 onvif.h 来用不跑 wsdl2h。不同 gSOAP 版本生成的头文件在类型别名、命名空间宏、回调签名上差异都很大换库版本后很可能编译不过。我一般会在自己的环境里从头生成一遍十次里有九次比修补旧文件快。生成出来的 onvif.h 就是你这台机器上的“接口契约”后续所有业务代码都以它为准。2.3 版本差异与前置依赖动手前的环境检查清单先确认本机的 gSOAP 工具在不在版本是否统一。很多发行版把 wsdl2h、soapcpp2 和运行库拆成不同包装的时候容易漏。我的检查顺序是这样which wsdl2h which soapcpp2 wsdl2h -h 21 | head -n 20 pkg-config --modversion libxml-2.0 2/dev/null pkg-config --modversion openssl 2/dev/nullwsdl2h -h 的输出里通常能看到版本号soapcpp2 的版本可以和它对照。两边的版本如果差了一个大版本生成代码和运行库之间容易出符号不匹配第五章第一个坑讲的就是这个现象。依赖方面重点看三样libxml2gSOAP 启用 DOM 解析或 WS-Security 时会用到编译宏是 DWITH_DOM。openssl做 Digest 认证、HTTPS 传输时必用编译宏是 DWITH_OPENSSL。zlib处理 SOAP 压缩传输嵌入式环境里经常没装全。检查完再开始生成。如果是在交叉编译环境宿主机上的 gSOAP 工具只负责生成代码生成出来的 C 文件拿到目标工具链里编译但运行库 stdsoap2.c 必须和生成器同版本不能拿发行版里旧的 .so 凑数。3. 生成 ONVIF 的 C 框架从 WSDL 到可编译工程这一章是实操主流程。我按“整理 WSDL → wsdl2h → soapcpp2 → 编进工程”四步走。命令给的是常用形态具体细节按你本机的 gSOAP 版本微调。每条命令后面都有参数说明照着敲就行。3.1 先整理 WSDL 文件只挑你要的模块ONVIF 的 WSDL 是按功能点拆分的不是一个大文件包打天下。常见模块名devicemgmt.wsdl设备管理、media.wsdl媒体、ptz.wsdl云台、event.wsdl事件、recording.wsdl录像。每个 WSDL 又会引用 common.xsd 这类公共 Schema。常见做法是单独建一个目录把需要用到的 WSDL 和 XSD 放平再用 wsdl2h 一次引用多个文件。比如这次只做设备管理、媒体、PTZmkdir -p onvif-wsdl cd onvif-wsdl # 目录里放 devicemgmt.wsdl media.wsdl ptz.wsdl common.xsd目录整理这一步别省。WSDL 内部用相对路径互相引用如果文件分散在不同目录wsdl2h 找依赖的时候会多花时间排查报错信息还不直观。只挑需要的模块还有一个好处生成的代码体积小交叉编译时间短。如果你不确定后面要不要 PTZ建议一次加进来免得后面重新生成时影响已经写好的业务头文件。3.2 wsdl2h 生成 C 头文件参数与常见输出问题执行生成命令wsdl2h -c -s -o onvif.h \ -P http://www.onvif.org/ \ -t typemap.dat \ devicemgmt.wsdl media.wsdl ptz.wsdl参数说明-c生成纯 C 代码而不是 C对应 onvif.h 里不会有 std::string 这类类型。-s去掉 STL 依赖C 工程强烈建议加交叉编译时最省心。-o onvif.h指定输出头文件名后面 soapcpp2 用的就是它。-P http://www.onvif.org/把命名空间前缀统一挂到 ONVIF 域名下避免出现_ns1、_ns2这种随机前缀。-t typemap.dat指定类型映射表。重要参数不加它 xsd:string 可能映射成奇怪的结构体。如果你的 WSDL 引用了不在当前目录的公共 Schema需要加-I指定搜索目录wsdl2h -I ./onvif-wsdl -c -s -o onvif.h -t typemap.dat \ devicemgmt.wsdl media.wsdl ptz.wsdl常见的错误提示是Cannot open file ...。这时候优先查相对路径而不是怀疑工具坏了。生成完先打开 onvif.h 头部确认两件事命名空间宏有没有生成、基础类型有没有变成char *。如果基础类型不对回头看-t typemap.dat。为什么-P参数值得单独说因为它决定了后续生成的命名空间一致性。ONVIF 各模块的 targetNamespace 并不完全一样有的挂在http://www.onvif.org/ver10/device/wsdl有的挂在http://www.onvif.org/ver20/media/wsdl。不处理的话序列化报文里会冒出一堆_ns1、_ns2抓包看着乱部分设备严格解析时会直接判命名空间错误。用-P统一根路径后配合生成的 nsmap 表检查能挡掉八成报文兼容问题。3.3 soapcpp2 生成客户端与服务端骨架wsdl2h 产出的是“接口定义”还编译不了。接着用 soapcpp2 把它变成可编译 C 文件。生成客户端加服务端soapcpp2 -c -L -I /opt/gsoap/gsoap/import -x onvif.h只生成客户端少一些用不到的服务端代码soapcpp2 -c -L -C -I /opt/gsoap/gsoap/import -x onvif.h参数含义-c输出 C 代码。-L不生成 soapClientLib.c / soapServerLib.c 这类聚合模板文件需要的话也可以主动生成看工程组织习惯。-C只生成客户端代码。-S只生成服务端代码。-I指向 gSOAP 安装目录下的 import 目录里面放着 xsd.h 等基础定义路径改成你本机的实际路径。-x不生成 XML 示例文件省得目录里多出一堆测试报文。执行完检查生成物最核心的五个文件soapH.h、soapStub.h、soapC.c、soapClient.c、soapServer.c。如果只想要客户端soapServer.c 不会出现这符合预期。生成完建议顺手 grep 一下命名空间前缀和函数原型。比如你关心设备服务就搜tds__GetDeviceInformation看函数的参数列表是否和你手里的 WSDL 一致。这一步能提前拦截很多后面对接时才暴露的问题。3.4 进入工程编译链接库与 Makefile 写法生成完代码下一步是编进工程。假设工程结构是src/ main.c onvif.h soapH.h soapStub.h soapC.c soapClient.c soapServer.c stdsoap2.cMakefile 可以这样写CC gcc CFLAGS -I. -I/opt/gsoap/gsoap -O2 -DWITH_OPENSSL LDFLAGS -lssl -lcrypto -lz -lm SRCS main.c soapC.c soapClient.c soapServer.c stdsoap2.c OBJS $(SRCS:.c.o) all: onvif_demo onvif_demo: $(OBJS) $(CC) $(OBJS) -o $ $(LDFLAGS) %.o: %.c $(CC) $(CFLAGS) -c $ -o $ clean: rm -f $(OBJS) onvif_demo要点有三个。第一-I/opt/gsoap/gsoap要指向 gSOAP 源码目录因为 stdsoap2.c 编译时可能 include 同目录下的其他头文件。第二链接-lssl -lcrypto是因为 OpenSSL 的加解密和时间函数如果完全不用安全认证可以把 CFLAGS 里的 DWITH_OPENSSL 去掉。第三别把 stdsoap2.c 换成系统里的 libgsoap.so除非你非常确定版本与生成器一致。嵌入式交叉编译时同样把 stdsoap2.c 拿进目标平台一起编译不要图省事链接宿主机的库。4. 生成代码的骨架长什么样文件清单与业务填充方法生成完代码后需要知道每个文件管什么、业务逻辑填在哪。很多人对着一堆 .c/.h 发懵其实拆开看并不复杂。4.1 六个关键文件各自管哪一段文件作用需要动的地方onvif.hwsdl2h 输出的接口定义通常不改改完要重跑 soapcpp2soapStub.h所有结构体的完整定义排查字段时看这里soapH.h编译总入口声明函数和结构体业务代码 include 它soapC.c所有序列化/反序列化实现一般不动soapClient.c调用对端服务的函数实现一般不动soapServer.c服务端分发框架与回调入口回调函数指向自己的实现还有一个常见文件 soapClientLib.c / soapServerLib.c用了-L就不会生成。有些工程把 soapC.c、soapClient.c、soapServer.c 统称“生成代码”建议单独放一个 gen/ 目录下次重新生成时整体替换不污染手写业务代码。4.2 服务端回调函数的注册与填充如果做设备端soapServer.c 已经为每个操作定义了回调函数。比如GetDeviceInformation的回调函数原型大致是这样int tds__GetDeviceInformation(struct soap *soap, struct _tds__GetDeviceInformation *req, struct _tds__GetDeviceInformationResponse *resp) { resp-Manufacturer soap_strdup(soap, DemoVendor); resp-Model soap_strdup(soap, IPC-Demo); resp-FirmwareVersion soap_strdup(soap, 1.0.0); return SOAP_OK; }逻辑说明三个参数分别是 soap 运行环境、请求结构、响应结构。响应结构里每个字段名来自 WSDL 里的返回元素。这个函数不是你在 main 里直接调用的而是被 soap_serve 或 soap_serve_request 在收到对应 SOAP 请求后自动调用。函数返回SOAP_OK表示处理成功业务判断失败时可以设置soap-error SOAP_FAULT框架自动生成 SOAP Fault 报文。参数说明soap_strdup是 gSOAP 的字符串复制函数它把副本放进 soap 上下文管理的内存池后续序列化阶段仍能访问。这里不能直接写resp-Manufacturer DemoVendor因为 gSOAP 解析结构体时可能尝试释放这块内存常量区指针会造成崩溃。响应字段多的时候用soap_malloc先分配空间再逐字段填。4.3 客户端soap_call 系列接口的调用方式如果做对接平台或上位机客户端代码用 soap_call 系列函数。函数名格式是soap_call___开头后面跟命名空间前缀和方法名。常见前缀对应关系tds 是设备服务trt 是媒体服务ptz 是云台服务。调用设备时间接口的示意代码#include soapH.h #include soapStub.h struct soap *soap soap_new(); struct _tds__GetSystemDateAndTime req; struct _tds__GetSystemDateAndTimeResponse resp; memset(req, 0, sizeof(req)); memset(resp, 0, sizeof(resp)); if (soap_call___tds__GetSystemDateAndTime( soap, http://192.168.1.64/onvif/device_service, NULL, req, resp) ! SOAP_OK) { soap_print_fault(soap, stderr); soap_end(soap); soap_free(soap); return -1; } printf(UTC time: %04d-%02d-%02d %02d:%02d:%02d\n, resp.UTCDateTime-Date.Year, resp.UTCDateTime-Date.Month, resp.UTCDateTime-Date.Day, resp.UTCDateTime-Time.Hour, resp.UTCDateTime-Time.Minute, resp.UTCDateTime-Time.Second); soap_end(soap); soap_free(soap);逻辑说明soap_new 创建独立的 soap 调用环境请求和响应结构体先清空避免把栈里的随机值当字段用soap_call 传入端点地址和 SOAPAction调用后立刻判断返回值出错时用 soap_print_fault 打印错误信息。参数说明端点地址是设备 SOAP 服务地址通常是/onvif/device_service结尾SOAPAction 传 NULL 是常见做法ONVIF 设备大都忽略但个别旧设备要求固定 Action遇到 500/400 响应时回查一下这个参数。要注意前缀对应关系。如果 onvif.h 里设备服务映射成了tds__函数名才是这种形态。用了-P统一命名空间后前缀和 WSDL 的 targetNamespace 一一对应不要硬编码其他前缀。4.4 内存管理边界soap_malloc 与临时变量的坑gSOAP 在 C 语言模式下有自己的内存管理规则。简单说soap 上下文里分配的对象soap_malloc、soap_strdup、soap_new_xxx 系列生命周期跟着 soap_end / soap_free 走。业务代码如果需要把设备返回的数据存到更长的生命周期一定要自己深拷贝static char g_model[64]; snprintf(g_model, sizeof(g_model), %s, resp.Model ? resp.Model : );这里用 snprintf 拷贝而不是g_model resp.Model正是为了断开与 soap 内存池的关联。响应结构体经过 soap_end 后内部指针指向的内容会失效。这个问题的典型表现是“第一次调用正常第二次调用崩溃”排查时非常容易蒙。还有一点线程相关一个 soap 上下文不能同时在多个线程里调用 soap_call。常见做法是每个线程 soap_new 一个实例线程退出时 soap_free不共享上下文。我见过有人图省事把全局 soap 变量用在多线程里结果同一个请求两个线程发出不同内容查了很久才发现是上下文串了。5. 生成 ONVIF 框架的五个常见坑现象、原因与方案这个坑清单是我实际跑过几轮后留下的记录每条按“现象 → 原因 → 解决”来写可以直接对照排查。5.1 链接报错一堆 undefined reference工具链版本错配现象代码编译都很顺利但链接时报undefined reference to soap_begin_send、undefined reference to soap_getelement这类错误而且数量极多。原因soapcpp2 根据 onvif.h 生成的源码里调用的运行库函数版本和当前链接的 libgsoap 不一致。最常见的是 wsdl2h / soapcpp2 来自新装的 gSOAP 包而系统里链接的是旧版 libgsoap.so两个大版本内部接口改动很大符号对不上。解决不要链接系统 libgsoap.so改把生成器同目录下的 stdsoap2.c 直接编进工程。Makefile 里把 stdsoap2.c 加入 SRCS去掉-lgsoap保证生成器和运行库同源。这个做法在交叉编译环境里尤其重要宿主机 .so 根本不能直接用。5.2 生成的基本类型不对typemap.dat 没加载现象生成的 onvif.h 里xsd__string没有变成char *而是变成struct指针或std::string后续代码用到字符串时编译报错。原因wsdl2h 处理 XML Schema 类型映射时默认映射对纯 C 工程不友好需要 typemap.dat 告诉它xsd__string映射成char *、xsd__int映射成int。命令里漏了-t typemap.dat或者路径给错映射没生效。解决确认 wsdl2h 命令行里有-t typemap.dat且 typemap.dat 中格式类似xsd__string | char *。gSOAP 安装目录自带一份 typemap.dat 可以直接沿用要加 ONVIF 特有类型就追加规则后放在工程目录里用相对或绝对路径传给-t。生成完成后可以打开 onvif.h 搜索char *确认映射已经落地。5.3 SOAP 序列化失败命名空间前缀不统一现象客户端调设备接口时soap_print_fault 输出类似SOAP 1.1 fault: Invalid namespace或Wrong namespace抓包看报文里前缀是_ns1、_ns2。原因wsdl2h 没有显式指定命名空间映射ONVIF 各模块的 targetNamespace 各不相同工具自动生成_ns1、_ns2这类随机前缀和设备端严格解析的命名空间 URI 对不上。解决生成时用-P参数统一命名空间根路径比如-P http://www.onvif.org/。生成完成后打开 soapH.h 里的 SOAP_NAMESPACE 表检查实际 URI 是否符合 ONVIF 规范。表里每一行是“前缀、URI、序号”的结构发现重复或错位手动调整后重新编译也能修。5.4 WS-Security 链接错误生成时没准备插件现象实现设备认证时调用了soap_wsse_add_UsernameTokenText之类的函数链接时报undefined reference to soap_wsse_*。原因gSOAP 的 WS-Security 是以插件形式存在的wsseapi.c 和 dom.c 不在 soapcpp2 默认生成的代码里。同时 WS-Security 依赖 DOM 解析编译时需要 DWITH_DOM 宏默认 Makefile 编不过。解决把 gSOAP 源码里 wsse 目录下的 wsseapi.c、wsseapi.h、dom.c 加入工程编译选项加-DWITH_OPENSSL -DWITH_DOM链接加-lssl -lcrypto。注意启用 WS-Security 后生成的客户端函数签名会多出一个安全上下文参数原有的 soap_call 调用都要跟着改。编译报错时会提示得很清楚照着改即可。5.5 回调返回后数据丢失或段错误内存生命周期没管住现象服务端回调函数把响应字段指向局部数组比如resp-Manufacturer local_buf函数返回时看似正常但实际序列化响应时读到了悬垂指针轻则返回空字符串重则段错误。原因gSOAP 服务端流程是“收到请求 → 调用回调 → 序列化响应 → 发送”回调返回并不是响应处理结束局部数组在回调返回时已经失效。解决响应结构体里的所有指针字段用soap_strdup或soap_malloc分配生命周期交给 soap 上下文。需要复制一段字节时用soap_memdup配合长度参数不要直接赋栈地址。这个坑最容易出现在刚上手的人身上我每次 review 生成代码第一眼看的就是响应字段的赋值方式。6. 验证这套 ONVIF 代码能跑回环自测与进阶习惯6.1 用最小 main 跑通回环生成完代码后最担心的就是“不知道跑没跑起来”。常见做法是先做一个回环测试工程里同时保留 soapClient.c 和 soapServer.cmain 函数先启动本地服务再调用客户端函数访问它验证请求、回调、序列化、反序列化全链路是否正确int main(void) { struct soap *soap soap_new(); /* 服务端初始化并监听本地端口 */ soap_bind(soap, 127.0.0.1, 18080, 100); if (soap_accept(soap) SOAP_OK) { soap_serve(soap); } /* 客户端调用自己的服务 */ soap_call___tds__GetDeviceInformation(soap, http://127.0.0.1:18080, NULL, req, resp); soap_free(soap); return 0; }这个方式不需要真设备能把 gSOAP 生成层的问题过滤掉八成。回环通了再连真实 IPC 验证地址、认证这些外围问题。6.2 进阶习惯每次生成都留一份环境快照回头看我自己的习惯每次换环境重跑这套流程都会把 gSOAP 版本号、typemap.dat 内容、wsdl2h 和 soapcpp2 的完整命令复制进一份 build 日志和生成的头文件一起存档。这样出现诡异问题时有退路能对着版本差异快速定位。从那以后我每次换一台新机器跑 gSOAP都会强制走一遍“查版本 → 整理 WSDL → 生成头文件 → 生成源码 → 编译验证”的流程确认五步全过才继续写业务。这套流程帮我挡掉了不少查错时间希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

Zint+Zlib+Libpng预编译库集成指南:Windows下CMake生成条码PNG

Zint+Zlib+Libpng预编译库集成指南:Windows下CMake生成条码PNG

简介:面向Windows开发者的预编译库合集,内含Zint、Zlib与Libpng三个开源库,专为Visual Studio 2015环境下的32位和64位工程准备,涵盖debug与release模式,可直接集成用于条形码/二维码生成、数据压缩解压及PNG图像读写。…

📅 2026/10/15 18:09:07
210+ AI开源技术大咖汇聚深圳!GOSIM Shenzhen 2026完整日程发布

210+ AI开源技术大咖汇聚深圳!GOSIM Shenzhen 2026完整日程发布

10月16—17日,全球开源创新峰会 GOSIM Shenzhen 2026 将在深圳南山伊敦酒店举行。自 2023 年以来,GOSIM 已先后走过上海、北京、巴黎、杭州等城市,第七站来到深圳。本届大会将重磅迎来 210 余位全球技术大咖和 2000 余位开发者,围…

📅 2026/10/15 18:09:07
MonkeyDev 使用指南:基于 Xcode 的 CaptainHook/Logos 插件开发与免越狱 App 注入调试

MonkeyDev 使用指南:基于 Xcode 的 CaptainHook/Logos 插件开发与免越狱 App 注入调试

开发工具移动开发 【免费下载链接】MonkeyDev CaptainHook Tweak、Logos Tweak and Command-line Tool、Patch iOS Apps, Without Jailbreak. 项目地址: https://gitcode.com/gh_mirrors/mo/MonkeyDev 点击查看 免费下载 导读:MonkeyDev 是 iOSOpenDev …

📅 2026/10/15 18:04:06
MORE NEWS

更多资讯

📰

从 neat-annotations 学现代 CSS 新特性:light-dark()、oklch 与 @property 彩虹动画实战

【免费下载链接】neat-annotations Hand-drawn CSS annotations for inline content 项目地址: https://gitcode.com/gh_mirrors/ne/neat-annotations 点击查看 免费下载 neat-annotations 是一个纯 CSS 实现的手绘风格网页注释库,没有 JavaScript、没有…

📰

20260331 基于物联网技术的河流水位监测系统设计

https://pan.baidu.com/s/1IicYYxJikK4Y4nRBqE4Tiw?pwd9efyhttps://pan.baidu.com/s/1IicYYxJikK4Y4nRBqE4Tiw?pwd9efy本课题围绕河流水位的实时监测与远程管理,基于物联网技术对系统进行整体设计与实现,主要研究内容如下: (1&a…

📰

S7-PLCSIM V17仿真调试完全指南:版本、监控与排错技巧

简介:一份面向西门子 PLC 工程师与自动化初学者的 S7-PLCSIM V17 中文帮助文档与操作说明合集,用于解决 PLC 模拟仿真环境搭建、程序调试及与 TIA Portal/STEP 7 集成使用中的常见疑问。压缩包内仅含 1 个 PDF 文件,容量约 25.95MB&#xff0…

📰

嵌入式场景下用C语言手写HTML解析器:状态机设计与容错实践

简介:这是一份面向C/C初学者与网页解析入门者的轻量级HTML解析实现,核心代码仅30余行,便于快速理解标记语言解析的基本原理。资源包共72个文件,以cpp与h源码文件为主,辅以obj、pdb、ilk等Visual Studio编译中间产物&am…

📰

Qt RTSP播放器实战:FFmpeg解码与低延迟优化

简介:本资源面向具备一定C与Qt基础的开发者,提供一套基于Qt、RTSP协议与FFmpeg库实现的视频流播放器完整工程,可用于远程监控、视频会议、在线教育等需要多路实时视频播放的场景。工程重点实现三通道视频流同时播放与截图功能,通过…

📰

SHT3x温湿度传感器驱动开发:从原理到避坑全指南

简介:SHT3x 温湿度传感器代码包面向嵌入式开发初学者与物联网应用工程师,围绕盛思锐 SHT3x 高精度温湿度传感器,提供一套基于 STM32 平台的完整示例工程,帮助解决环境监测、智能家居、工业自动化等场景中温湿度数据精确采集与解析…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬