Windows Runtime 进程内组件代理/存根(Proxy/Stub)实战:ProxyStubsForWinRTComponents 示例深度解析
示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载导读本文基于 Windows-universal-samples 仓库中的 ProxyStubsForWinRTComponents 示例深入讲解如何为 Windows RuntimeWinRT进程内组件in-process component创建代理与存根proxies and stubs使其能被 C、JavaScript 与 C# 三种语言无缝消费。读完本文你将掌握WinRT 组件服务器server的接口 IID 声明方式、代理/存根 DLL*_PS.vcxproj的构建链路、.def导出表的作用以及 C/CX、WRL、C#、JS 四种客户端消费同一组件的实际写法与构建、部署、运行步骤。示例定位跨语言消费的进程内组件该示例的核心目标是演示一种典型的 UWP 组件架构场景组件以进程内方式承载in-process但消费方横跨 C含 C/CX 投影与 WRL、C# 与 JavaScript 三种语言。要让同一份组件实现被不同语言正确投影和调用WinRT 需要借助标准的 COM 代理/存根机制进行接口注册与调用转发这正是本示例名字 ProxyStubsForWinRTComponents 的由来。从仓库目录结构看示例根目录下提供两套独立解决方案区别在于组件服务器Server的编写语言cpp/ProxyStubsForWinRTComponents.sln服务器使用 C/CXcppcx编写cs/ProxyStubsForWinRTComponents.sln服务器使用 C# 编写。两套解决方案内部都包含完全相同的四类工程Server组件服务器、PS代理/存根工程、C 客户端、C# 客户端与 JS 客户端。README 中提到的语言选择C、C# 或 JavaScript对应解决方案目录仓库实际随源码分发的是cpp与cs两套解决方案而js目录如 cpp/js内为客户端代码。组件服务器用显式 IID 定义跨语言接口接口与实现Bread 与 Oven组件服务器位于Microsoft.SDKSamples.Kitchen命名空间下围绕厨房烤箱业务模型定义了两组类型C/CX 与 C# 各有完全等价的实现类型定义说明OvenTemperaturecpp/Server/BreadTypes.h / cs/Server/OvenServer.cs枚举Low、Medium、High三档预热温度Dimensions同上值类型value struct含Depth、Height、Width三个double字段IBread/Breadcpp/Server/BreadServer.h只读属性Flavor口味IAppliance/IOven/Ovencpp/Server/OvenServer.hVolume只读属性、ConfigurePreheatTemperature、BakeBread、BreadBaked事件关键手法为接口显式声明 IID代理/存根机制的核心是 COM 接口注册因此接口的 IID接口标识符必须稳定且可预期。C/CX 版源码在接口声明处通过[uuid(...)]显式固定 IID源码注释明确写道Explicitly declare IIDs to make it easier to author the proxy stub interface registration见 OvenServer.hIAppliance332FD2F1-1C69-4C91-949E-4BB67A85BDC5IOven6A112353-4F87-4460-A908-2944E92686F3IBread699B1394-3CEB-4A14-AE23-EFEC518B088BC# 版则用[Guid(...)]特性声明同一组 IID见 cs/Server/OvenServer.cs 与 cs/Server/BreadServer.cs。两套语言的 IID 必须一致这正是后续代理/存根工程中PROXY_CLSID预处理器宏能正确注册接口的前提。服务器业务逻辑以事件驱动模拟异步烘焙OvenServer.cpp 展示了服务器侧的完整行为Volume属性由三个维度相乘得出Width * Height * DepthConfigurePreheatTemperature对温度参数做范围校验越界即抛出Platform::InvalidArgumentExceptionBakeBread根据当前温度档位选择预热时长Low→100 个时间单位、Medium→200、High→300随后通过ThreadPoolTimer::CreateTimer在后台线程完成烘焙再触发BreadBaked事件把新创建的Bread实例连同Oven一并交给订阅者。C# 实现OvenServer.cs与之一一对应同样的枚举范围校验、ThreadPoolTimer计时与BreadBaked事件触发。组件引入线程池回调意味着事件会在非 UI 线程触发客户端侧如何处理跨线程的 UI 更新正是示例场景要演示的重点之一。代理/存根工程跨语言调用的翻译层PS 工程结构代理/存根由独立的 DLL 工程产出即ProxyStubsForWinRTComponentsPS.vcxprojC 与 C# 解决方案各有一份内容一致见 cpp/Server/ProxyStubsForWinRTComponentsPS.vcxproj。从工程文件可以读出以下关键配置输出类型DynamicLibrary动态库TargetName为Microsoft.SDKSamples.Kitchen.Proxies即最终生成Microsoft.SDKSamples.Kitchen.Proxies.dll源文件编译dlldata.c、Microsoft.SDKSamples.Kitchen_i.c、Microsoft.SDKSamples.Kitchen_p.c三个文件——这三个文件是 MIDL 编译器处理 IDL 后生成的标准代理/存根代码_i.c为接口标识定义_p.c为代理/存根实现dlldata.c为 DLL 数据段注册表在仓库源码中它们属于构建产物MIDL 输入Midl项引用Microsoft.SDKSamples.Kitchen.idl即代理/存根代码由该 IDL 驱动生成预处理器宏PROXY_CLSIDIID___x_ABI_CMicrosoft_CSDKSamples_CKitchen_CIAppliance把代理类的 CLSID 直接绑定到IAppliance接口的 IID 上实现按接口注册代理类链接依赖rpcrt4.libRPC 运行时、runtimeobject.libWinRT 运行时对象部分配置还包含mincore.lib模块定义文件OvenServerPS.def。.def 导出表代理 DLL 的标准入口OvenServerPS.def 内容非常简短但语义明确LIBRARY Microsoft.SDKSamples.Kitchen.Proxies.dll EXPORTS DllCanUnloadNow PRIVATE DllGetClassObject PRIVATEDllGetClassObject是 COM 类工厂的标准入口供系统按 CLSID此处即PROXY_CLSID对应的IApplianceIID获取代理/存根类工厂DllCanUnloadNow供 COM 决定何时可安全卸载 DLL。这两个导出是任何代理/存根 DLL 的身份证也是连接 COM 运行时与 WinRT 接口注册表的桥梁。C# 服务器的 IDL 生成链路C# 编写的组件没有源码级 IDL 文件因此 cs/Server/ProxyStubsForWinRTComponents_server.csproj 在PostBuildEvent中调用了winmdidl工具call $(DevEnvDir)..\..\VC\vcvarsall.bat x86 winmdidl /outdir:$(ProjectDir)\ $(TargetPath)即构建 C# 服务器时先产出.winmd工程OutputType为winmdobj再由winmdidl把元数据反推出 IDL供 PS 工程的 MIDL 步骤消费。C/CX 与 C# 两条路线殊途同归最终都收敛到同一个 IDL → MIDL → 代理/存根 DLL 的构建流水线这是本示例最有价值的架构知识点。客户端消费四种语言的投影对照C/CX 投影Scenario1_OvenClientScenario1_OvenClient.xaml.cpp 演示了 C/CX 对进程内组件最典型的消费方式创建对象ref new Oven(dimensions)使用Dimensions值类型传参属性访问myOven-Volume直接以属性语法取值事件注册与注销可注册多个BreadBaked处理器C/CX 投影暴露事件注册令牌token通过返回值保存 token再用-精确移除——示例中注册了三个处理器并移除了第三个运行时可看到Event Handler 3不会触发调用方法BakeBread(Sourdough)后ThreadPoolTimer触发事件再次调用ConfigurePreheatTemperature(OvenTemperature::High)改变预热档位后再次烘焙。事件在后台线程触发处理器内通过Dispatcher-HasThreadAccess判断线程归属并用Dispatcher-RunAsync把 UI 更新 lambda 调度回 UI 线程——这是 UWP 跨线程 UI 更新的标准模式。WRL 客户端Scenario2_OvenClientWRL在同一解决方案的客户端 C 工程中还提供了Scenario2_OvenClientWRL场景文件见 cpp/cpp 目录。从工程结构推断该场景使用 WRLWindows Runtime C Template Library以 ABI 层 COM 接口方式消费同一个Oven组件与 Scenario1 的 C/CX 语言扩展写法形成对照适合需要精细控制引用计数与 COM 生命周期的场景。两个场景共用同一组件服务器恰好验证了代理/存根机制对同一接口的多种消费形态的兼容性。C# 与 JavaScript 客户端C# 客户端工程cs/cs与 JS 客户端cpp/js 或 cs/js同样包含Scenario1_OvenClient烤箱调用与Scenario2_CustomException自定义异常两类场景JS 客户端为 WinJS HTML 页面scenario1-oven-client.html/scenario2-custom-exception.html及其对应js文件以 JavaScript 的 WinRT 投影语法如new Kitchen.Oven(...)与事件订阅调用同一组件自定义异常场景从文件命名推断用于演示异常在跨语言调用链中如何经代理/存根传递——C 侧Platform::InvalidArgumentException与 C# 侧ArgumentException在服务器端抛出后客户端各语言投影如何捕获与呈现。系统要求README 明确列出运行环境约束见 README.md客户端ClientWindows 10服务器ServerWindows Server 2016 Technical Preview手机PhoneWindows 10。此外示例需要Visual Studio才能构建、Windows 10才能运行。仓库目标平台版本为10.0.22621.0见 PS 工程 与 C# 服务器工程构建环境需具备对应的 Windows SDK。构建与运行构建步骤若以 ZIP 方式下载示例请解压整个归档而不仅是目标示例所在文件夹——示例依赖仓库根目录的 SharedContent 共享资源工程中通过SharedContentDir宏向上查找 LICENSE 定位只解压单文件夹会导致共享依赖缺失启动 Visual Studio选择FileOpenProject/Solution在解压后的目录中依次进入Samples子文件夹 → 本示例子文件夹 → 首选语言的子文件夹C 或 C#双击其中的 Visual Studio 解决方案文件.sln按CtrlShiftB或选择BuildBuild Solution完成构建。运行步骤运行方式取决于你只需要部署还是部署并运行仅部署选择BuildDeploy Solution部署并运行调试按F5或选择DebugStart Debugging部署并运行不调试按CtrlF5或选择DebugStart Without Debugging。关键要点回顾显式 IID 是代理/存根的基础C/CX 用[uuid]、C# 用[Guid]声明完全一致的接口标识PS 工程再以PROXY_CLSID宏把代理类绑定到IAppliance的 IID构建流水线殊途同归C/CX 直接提供接口定义C# 由winmdidl从 winmd 反推 IDL两者都汇入「IDL → MIDL生成dlldata.c/_i.c/_p.c→ 代理 DLL」的同一条链路.def导出是 COM 入口DllGetClassObject与DllCanUnloadNow是代理/存根 DLL 被系统识别与加载的门面客户端形态多样但语义一致C/CX 的事件 token、WRL 的 ABI 直调、C# 与 JS 的投影语法消费的是同一组件、同一组接口这正是代理/存根机制价值的直接证明。如需深入阅读源码推荐按此顺序浏览README.md → OvenServer.h接口与 IID→ OvenServer.cpp服务器逻辑→ ProxyStubsForWinRTComponentsPS.vcxproj代理/存根构建→ Scenario1_OvenClient.xaml.cpp客户端投影与事件处理。赞分享示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载相关推荐CANN Runtime 多进程 IPC Notify 共享与进程白名单校验实战0_ipc_notify_withpid 示例深度解析CANN Runtime 多进程 IPC Notify 共享与进程白名单校验实战0_ipc_notify_withpid 示例深度解析 导读 本文基于 CANCANNAscend人工智能性能剖析系统编程CANN Runtime 内存管理与数据搬运实战指南基于 memory 示例集的 14 个场景深度解析CANN Runtime 内存管理与数据搬运实战指南基于 memory 示例集的 14 个场景深度解析 本指南围绕 CANN Runtime 开源仓库中 exCANNAscend人工智能性能剖析系统编程Azure文件共享数据同步AzCopy v10 sync命令高级用法Azure文件共享数据同步AzCopy v10 sync命令高级用法 AzCopy v10是一款功能强大的Azure存储数据传输工具其中sync命令为文件共上一篇P6Spy完整配置指南从基础设置到高级调优下一篇Go语言GUI开发终极指南Walk工具包从入门到精通创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

企业级 Agent 异步并发实战:从线上事故到高并发架构

企业级 Agent 异步并发实战:从线上事故到高并发架构

1. 从一次线上事故说起:企业级 Agent 的异步并发到底难在哪去年下半年我接手了一个企业级 Agent 平台的稳定性治理工作,这个平台对外提供智能体编排、工具调用、多轮对话记忆、RAG 检索增强等能力,日均请求量在百万级别。上线初期一切看起来都…

2026/9/25 8:47:09 阅读更多 →
Flink 交互式性能剖析(Profiler)实战指南:基于 async-profiler 的 JobManager/TaskManager 在线采样

Flink 交互式性能剖析(Profiler)实战指南:基于 async-profiler 的 JobManager/TaskManager 在线采样

大数据流处理批处理数据工程 【免费下载链接】flink 项目地址: https://gitcode.com/gh_mirrors/fli/flink 点击查看 免费下载 自 Flink 1.19 起,Flink 通过 Web UI 集成了 async-profiler 为主体,结合仓库中的 REST 配置项、ProfilingServi…

2026/9/25 8:47:09 阅读更多 →
毕业生实习管理系统部署实战:从解压到跑通全流程避坑指南

毕业生实习管理系统部署实战:从解压到跑通全流程避坑指南

简介:毕业生实习管理系统是一套面向高校、企业、教师和学生的信息化管理平台,针对传统实习流程中岗位信息分散、申请审批繁琐、过程跟踪困难等痛点,提供从学生注册、岗位浏览、实习申请、日志提交,到教师审核指导、企业岗位发布、…

2026/9/25 8:47:09 阅读更多 →

最新新闻

DeepSeek-Harness:CLI与Web UI双入口实操Agent开发

DeepSeek-Harness:CLI与Web UI双入口实操Agent开发

上一篇文章把 Harness 和 Agent 的区别掰扯清楚了,很多朋友看完还是觉得差点意思:概念懂了,下一步怎么跑起来?这次直接从 DeepSeek-Harness 最常用的两个入口讲起——CLI 和 Web UI。一个是纯命令行操作,适合脚本化、自…

2026/9/26 13:56:32 阅读更多 →
iVentoy 批量装机实战:PXE 网络启动部署与自动化配置指南

iVentoy 批量装机实战:PXE 网络启动部署与自动化配置指南

1. 为什么我最终选择了 iVentoy 做批量装机 机房上架新机器,最烦的从来不是硬件安装,而是装系统。十几台甚至几十台机器,一台一台插U盘、选启动项、点下一步,一天下来人直接废掉。我最早用的是传统 PXE 方案,配 DHCP、…

2026/9/26 13:56:32 阅读更多 →
Matlab实现正则化逻辑回归:微芯片质检分类完整实战

Matlab实现正则化逻辑回归:微芯片质检分类完整实战

芯片一条产线跑下来,良率就是生命线。我在实际项目里用Matlab做过不少分类预测的活,正则化逻辑回归在微芯片质检这种“维度不高、样本不大、但噪声不小”的场景里,反而比一堆花里胡哨的集成模型更稳、更可解释。这套流程不光能跑通实验数据&a…

2026/9/26 13:56:32 阅读更多 →
基于Java+SSM+Flask的高校就业管理系统设计与实现

基于Java+SSM+Flask的高校就业管理系统设计与实现

毕业设计选“高校就业管理系统”的同学,这两年肉眼可见地多起来了。基本上每个学校和学院都在催就业数据,加上每年毕业季前老师都要统计就业率、学生要投简历、企业要来校招,这套系统的需求量一直很稳。而“基于JavaSSMFlask高校就业管理系统…

2026/9/26 13:56:32 阅读更多 →
Laya-CoreML 如何把Transformer送上Neural Engine:BC1L激活、1×1投影与逐头注意力的ANE图重写

Laya-CoreML 如何把Transformer送上Neural Engine:BC1L激活、1×1投影与逐头注意力的ANE图重写

Laya-CoreML 如何把Transformer送上Neural Engine:BC1L激活、11投影与逐头注意力的ANE图重写 【免费下载链接】laya-coreml Local Laya typed decisions on Apple Core ML and Neural Engine. Validated ports, ~5 ms short decisions on M3 Max, reproducible spee…

2026/9/26 13:56:32 阅读更多 →
UWB不止定位:用SR1120构建低功耗高速短距数据链路

UWB不止定位:用SR1120构建低功耗高速短距数据链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/26 13:55:32 阅读更多 →

日新闻

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、…

2026/9/26 0:00:25 阅读更多 →
学校官网模拟全流程实践:从页面布局到后端接口与部署

学校官网模拟全流程实践:从页面布局到后端接口与部署

如果你正在找一门 Web 大作业的题目,或者刚开始接触 Web 前端开发想做点能拿来展示的东西,“学校官网模拟”几乎是最稳的选择。题目看着简单,但要把导航、新闻列表、轮播 Banner、二级页面、后台数据都串起来,其实已经把前端布局、…

2026/9/26 0:00:25 阅读更多 →
超级玛丽游戏源码C++:从零搭建横版跳跃游戏工程

超级玛丽游戏源码C++:从零搭建横版跳跃游戏工程

简介:这是一份面向游戏开发初学者与C进阶学习者的超级玛丽(超级马里奥)游戏源码,基于C面向对象编程实现,适合想通过经典项目理解游戏主循环、角色类设计、地图关卡加载与物理碰撞检测的读者参考。压缩包共49个文件&…

2026/9/26 0:00:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/25 19:27:14 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/25 11:15:26 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/25 20:29:09 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/25 20:29:43 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/25 20:29:31 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/25 19:27:26 阅读更多 →