MFC调用C# DLL全链路指南:C++/CLI桥接实战
简介本资源是一份面向C/MFC开发者与.NET跨语言集成学习者的实战型技术包聚焦解决Windows平台下MFC应用程序调用C#编写的托管DLL这一典型互操作难题。资源包含完整可运行的工程实例覆盖C# DLL封装、P/Invoke接口定义、MFC端动态加载与函数调用全流程并附带线程安全与类型映射等关键注意事项说明。压缩包共49个文件以4个核心DLL含CsharpDLL.dll及IKVM系列运行时、2个cpp/h源文件、1个sln解决方案及1个exe可执行文件为主体辅以调试符号pdb、项目配置vcxproj和资源文件rc/res总大小22.48MB结构清晰便于逆向分析与二次开发。目前已有1802人学习下载读者可直接复现跨语言调用链路获取可调试的工程模板、完整的依赖配置方案及典型错误处理范例显著降低实际项目中MFC与C#协同开发的技术门槛。1. MFC调用C# DLL不是“跨语言玄学”而是可控的互操作工程解决Win32桌面应用快速集成.NET业务逻辑的刚需你在维护一个运行十年以上的MFC单文档界面程序突然要接入新上线的OCR识别服务——它由团队新成员用C# ML.NET封装成DLL带完整日志、配置热加载和异常重试机制。你不想重写整个UI层更不敢把.NET Framework版本强绑到客户老机器上。这时候“在MFC下调用C# DLL”就不是技术选修题而是交付倒计时下的必答题。它本质是Windows平台下COM互操作与CLR宿主机制的落地组合C#编译为托管DLL后通过C/CLI桥接层或Regasm注册为COM组件再由MFC以标准Win32方式调用。关键不在“能不能”而在“怎么让MFC进程安全加载CLR、传递非托管内存、捕获托管异常、且不因.NET版本冲突崩掉”。本文全程基于Visual Studio 2022 Windows 10/11实测覆盖从C# DLL导出函数签名设计、C/CLI封装层编写、MFC项目属性配置到内存生命周期管理的全链路。适合正在啃遗留系统升级任务的C工程师也适合刚接触混合编程的.NET开发者——你不需要懂IL汇编但得清楚__declspec(dllexport)和[ComVisible(true)]的生效边界。2. 为什么不能直接DllImportC# DLL导出函数的三种合规路径与选型依据MFC作为纯原生C框架无法直接#includeC#编译产物。强行用LoadLibraryGetProcAddress会触发System.BadImageFormatException——因为C#生成的是托管PE文件其入口点被JIT编译器接管而非传统Win32函数表。必须通过中间层解耦。常见方案有三COM注册调用、C/CLI桥接、以及.NET Core 3.1的逆向P/Invoke本文不采用因MFC项目多依赖.NET Framework。我们实测选择C/CLI桥接层它编译为混合模式DLL既能用#using mscorlib.dll引用托管类型又能用extern C导出C风格函数供MFC调用规避了COM注册的权限问题和GAC部署风险。而COM方案虽在旧项目中常见但需管理员权限注册、易受UAC拦截且CoCreateInstance失败时错误码晦涩如0x80040154常被误判为DLL未注册实则为位数不匹配。2.1 设计C# DLL的可导出接口避免字符串、集合、事件等托管特性的陷阱C#端必须剥离所有.NET专属类型仅暴露int、double、const char*、bool等C兼容类型。字符串传递采用“输入输出缓冲区”模式——MFC分配内存C#填充后返回实际长度。以下为实测可用的C#类定义注意[DllImport]在此处不适用它是给托管代码调用非托管用的// CSharpLogic.cs - 编译为 ClassLibrary (.NET Framework 4.7.2) using System; using System.Runtime.InteropServices; namespace OCRService { public class Engine { // 关键用static方法显式调用约定确保导出符号稳定 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int ProcessImageDelegate( IntPtr inputBuffer, // MFC传入的BMP数据指针 int bufferSize, IntPtr outputText, // MFC分配的char[]缓冲区 int outputSize, // 缓冲区字节数 out int actualLength); // 实际写入字节数含\0 // 此方法将被C/CLI封装层调用不直接暴露给MFC public static int ProcessImageInternal( IntPtr inputBuffer, int bufferSize, IntPtr outputText, int outputSize, out int actualLength) { try { // 将非托管内存转为托管byte[] byte[] imageData new byte[bufferSize]; Marshal.Copy(inputBuffer, imageData, 0, bufferSize); // 模拟OCR处理此处替换为真实ML.NET调用 string result OCR_RESULT: PASS_20240521; // 安全写入输出缓冲区防止越界 byte[] textBytes System.Text.Encoding.UTF8.GetBytes(result \0); if (textBytes.Length outputSize) { Marshal.Copy(textBytes, 0, outputText, textBytes.Length); actualLength textBytes.Length; return 0; // 成功 } else { actualLength 0; return -1; // 缓冲区不足 } } catch (Exception ex) { // 托管异常必须捕获否则会炸穿到MFC Console.WriteLine($C#内部异常: {ex.Message}); actualLength 0; return -2; } } } }提示ProcessImageInternal不加[DllExport]——C#本身不支持直接导出非托管函数。.NET Framework下必须依赖第三方工具如UnmanagedExports但会引入额外依赖且调试困难。本文方案绕过此限制由C/CLI承担导出职责。2.2 编写C/CLI桥接层混合模式DLL的编译配置与函数导出新建C/CLI类库项目名称BridgeLayer目标框架设为.NET Framework 4.7.2必须与C# DLL一致。关键配置项目属性 → 常规 → “公共语言运行时支持”设为/clrC/C → 语言 → “启用运行时类型信息”设为是。桥接层核心是两件事1用#using引用C# DLL2用extern C导出C函数。代码如下// BridgeLayer.h #pragma once #include targetver.h #using OCRService.dll // 引用C#项目输出 using namespace System; using namespace OCRService; // 导出C风格函数供MFC调用 extern C { __declspec(dllexport) int __cdecl ProcessImage( void* inputBuffer, int bufferSize, char* outputText, int outputSize, int* actualLength); }// BridgeLayer.cpp #include BridgeLayer.h #include vcclr.h // for pin_ptr int __cdecl ProcessImage( void* inputBuffer, int bufferSize, char* outputText, int outputSize, int* actualLength) { try { // 将非托管指针转为托管IntPtr IntPtr inputPtr(inputBuffer); IntPtr outputPtr(outputText); // 调用C#静态方法注意参数顺序与C#定义严格一致 int result Engine::ProcessImageInternal( inputPtr, bufferSize, outputPtr, outputSize, *actualLength); return result; } catch (const std::exception e) { // C异常需转为整数错误码 return -3; } catch (...) { // 未知异常兜底 return -4; } }参数说明__cdecl调用约定确保参数从右向左压栈与MFC默认一致__declspec(dllexport)使函数出现在DLL导出表pin_ptr在此未显式使用因IntPtr构造函数已处理内存固定。若C#方法需修改输入缓冲区内容才需pin_ptr锁定GC堆内存。3. MFC项目配置四步打通非托管调用链避开LNK2019和模块初始化失败MFC项目假设名为MFCDemo需完成四类配置1链接桥接DLL的lib文件2声明外部函数3处理.NET运行时初始化4管理DLL生命周期。任何一步缺失都会导致链接失败或运行时崩溃。3.1 生成并链接桥接层的.lib文件解决LNK2019“未解析的外部符号”C/CLI项目默认不生成.lib文件因其导出的是托管符号。需手动开启项目属性 → 链接器 → 高级 → “导入库”设为BridgeLayer.lib。编译后在MFC项目中添加附加包含目录$(SolutionDir)BridgeLayer\附加库目录$(SolutionDir)BridgeLayer\$(Configuration)\附加依赖项BridgeLayer.lib然后在MFC源文件如MainFrm.cpp顶部声明函数// 在头文件或CPP文件顶部 extern C { typedef int (__cdecl *PFN_ProcessImage)( void*, int, char*, int, int*); static PFN_ProcessImage g_pfnProcessImage nullptr; }3.2 在MFC中动态加载桥接DLL并获取函数地址规避静态链接的版本绑定不推荐#pragma comment(lib, BridgeLayer.lib)因会导致MFC启动时强制加载.NET运行时而此时CLR尚未初始化。应改用LoadLibraryGetProcAddress动态加载// 在CMainFrame::OnCreate()中 BOOL CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CMDIFrameWnd::OnCreate(lpCreateStruct) -1) return -1; // 1. 加载桥接DLL路径需确保可访问 HMODULE hBridge LoadLibrary(_T(BridgeLayer.dll)); if (!hBridge) { AfxMessageBox(_T(无法加载BridgeLayer.dll请检查路径及.NET Framework版本)); return -1; } // 2. 获取函数地址 g_pfnProcessImage (PFN_ProcessImage)GetProcAddress(hBridge, ProcessImage); if (!g_pfnProcessImage) { AfxMessageBox(_T(BridgeLayer.dll中未找到ProcessImage函数)); FreeLibrary(hBridge); return -1; } // 3. 关键初始化CLR宿主环境——必须在调用任何托管代码前执行 // 此处调用.NET Framework的CorBindToRuntimeEx但MFC无现成封装 // 实测发现首次调用C/CLI导出函数时CLR会自动初始化无需手动调用 // 故此步可省略但需确保BridgeLayer.dll与MFC同为x86或x64 return 0; }注意LoadLibrary路径必须为绝对路径或位于PATH环境变量中。若DLL放在MFC可执行目录同级用_T(BridgeLayer.dll)即可若在子目录如./libs/BridgeLayer.dll需拼接完整路径。3.3 在MFC中安全调用内存分配、错误处理与资源释放调用时需为输出字符串预分配足够空间并检查返回值void CMainFrame::OnOcrProcess() { if (!g_pfnProcessImage) return; // 1. 准备输入数据模拟BMP内存块 const int INPUT_SIZE 1024 * 1024; // 1MB std::vectorBYTE inputBuffer(INPUT_SIZE, 0xAA); // 2. 分配输出缓冲区UTF8编码预留2KB const int OUTPUT_SIZE 2048; std::vectorchar outputBuffer(OUTPUT_SIZE, 0); int actualLength 0; // 3. 调用桥接函数 int result g_pfnProcessImage( inputBuffer.data(), static_castint(inputBuffer.size()), outputBuffer.data(), OUTPUT_SIZE, actualLength); // 4. 处理结果 if (result 0 actualLength 0) { CString strResult(outputBuffer.data()); AfxMessageBox(strResult); } else { CString errMsg; errMsg.Format(_T(OCR处理失败错误码%d), result); AfxMessageBox(errMsg); } }关键细节std::vectorchar确保内存连续且自动析构CString构造函数能正确处理UTF8字符串需项目设置为UnicodeactualLength包含末尾\0故outputBuffer.data()可直接转CString。4. 避坑MFC调用C# DLL的5个血泪经验每一条都来自真实翻车现场混合编程的坑往往藏在“看似正常”的边缘场景。以下是某高校实验室在迁移图像处理模块时踩过的5个典型问题按发生频率排序4.1 现象MFC启动即崩溃事件查看器报错“CLR initialization failed”原因MFC项目平台目标x86/x64与C# DLL、C/CLI桥接层不一致。例如MFC设为x64而C#项目目标为x86LoadLibrary虽成功但首次调用时CLR尝试加载x86运行时失败。解决统一所有项目平台为目标x64或x86在解决方案配置管理器中逐个核对。特别注意C/CLI项目默认可能为Any CPU需手动改为x64。4.2 现象GetProcAddress返回NULL但DLL确实存在且dumpbin /exports可见函数名原因C/CLI导出函数名被C编译器修饰name mangling。dumpbin /exports BridgeLayer.dll显示的可能是?ProcessImage$$J0YAHPEAXHPEADHPEAHZ而非ProcessImage。解决在C/CLI头文件中extern C块必须包裹函数声明如2.2节所示且.cpp中实现时不能再加extern C——声明与定义需严格对应。重新编译桥接层后用dumpbin /exports确认导出名为ProcessImage。4.3 现象OCR返回乱码或CString显示为空白原因C#端用Encoding.UTF8.GetBytes()写入但MFCCString在Unicode模式下期望UTF16。CString(outputBuffer.data())会将UTF8字节流误读为ANSI字符。解决在C#端改用UTF16编码或在MFC端显式转换if (result 0 actualLength 0) { // 将UTF8字节流转为UTF16 CString int wideLen MultiByteToWideChar(CP_UTF8, 0, outputBuffer.data(), actualLength, NULL, 0); std::vectorwchar_t wideBuf(wideLen 1); MultiByteToWideChar(CP_UTF8, 0, outputBuffer.data(), actualLength, wideBuf.data(), wideLen); CString strResult(wideBuf.data()); AfxMessageBox(strResult); }4.4 现象多次调用后MFC内存占用飙升任务管理器显示私有工作集持续增长原因C# DLL中的静态资源如OCR模型缓存未释放且.NET GC未及时回收。C/CLI桥接层虽无托管对象但每次调用都会触发CLR JIT编译和临时对象创建。解决在C#端添加显式资源清理方法并在MFC退出前调用// C#中添加 public static void Cleanup() { // 释放模型、关闭日志等 }// C/CLI中导出 extern C __declspec(dllexport) void __cdecl CleanupEngine() { Engine::Cleanup(); }在CMainFrame::OnDestroy()中调用CleanupEngine()。4.5 现象客户机器安装.NET Framework 4.8后仍报错“未能加载文件或程序集”原因C# DLL引用了高版本NuGet包如Microsoft.ML3.0而客户机器仅装有.NET Framework 4.7.2运行时缺少对应程序集。解决在C#项目中将所有NuGet包版本锁死为.NET Framework 4.7.2兼容版本如Microsoft.ML用1.7.0并在发布时用ILMerge合并依赖或直接复制bin\Release下所有.dll到MFC目录。5. 进阶技巧用C/CLI实现双向回调与结构体传递让MFC真正“感知”C#状态当业务复杂度上升单纯“请求-响应”模式不够用。例如OCR处理需实时反馈进度、错误详情、甚至暂停指令。此时需在C/CLI中建立托管委托与非托管函数指针的映射实现C#主动回调MFC。5.1 定义MFC端的回调函数原型与注册接口在MFC头文件中声明回调类型及注册函数// 在MFC头文件中 typedef void (__cdecl *PFN_ProgressCallback)(int percent, const char* status); typedef void (__cdecl *PFN_ErrorCallback)(const char* message, int errorCode); // 全局变量存储回调函数指针 static PFN_ProgressCallback g_pfnProgressCb nullptr; static PFN_ErrorCallback g_pfnErrorCb nullptr; // 导出注册函数由C/CLI提供 extern C { __declspec(dllexport) void __cdecl RegisterCallbacks( PFN_ProgressCallback progressCb, PFN_ErrorCallback errorCb); }5.2 在C/CLI中桥接托管事件与非托管回调C#端定义事件// C#中 public static event Actionint, string OnProgress; public static event Actionstring, int OnError; public static void TriggerProgress(int p, string s) { OnProgress?.Invoke(p, s); }C/CLI中订阅事件并转发// BridgeLayer.h #pragma once #using OCRService.dll using namespace System; using namespace OCRService; // 全局回调指针需线程安全此处简化 static PFN_ProgressCallback g_pfnProgressCb nullptr; static PFN_ErrorCallback g_pfnErrorCb nullptr; extern C { __declspec(dllexport) void __cdecl RegisterCallbacks( PFN_ProgressCallback progressCb, PFN_ErrorCallback errorCb); __declspec(dllexport) int __cdecl ProcessImageWithCallback( void*, int, char*, int, int*); } // BridgeLayer.cpp void __cdecl RegisterCallbacks( PFN_ProgressCallback progressCb, PFN_ErrorCallback errorCb) { g_pfnProgressCb progressCb; g_pfnErrorCb errorCb; // 订阅C#事件 Engine::OnProgress gcnew Actionint, String^( [](int percent, String^ status) { if (g_pfnProgressCb) { // 将托管String转为非托管char* pin_ptrconst wchar_t wch PtrToStringChars(status); int len WideCharToMultiByte(CP_UTF8, 0, wch, -1, NULL, 0, NULL, NULL); std::vectorchar utf8buf(len); WideCharToMultiByte(CP_UTF8, 0, wch, -1, utf8buf.data(), len, NULL, NULL); g_pfnProgressCb(percent, utf8buf.data()); } }); Engine::OnError gcnew ActionString^, int( [](String^ msg, int code) { if (g_pfnErrorCb) { pin_ptrconst wchar_t wch PtrToStringChars(msg); int len WideCharToMultiByte(CP_UTF8, 0, wch, -1, NULL, 0, NULL, NULL); std::vectorchar utf8buf(len); WideCharToMultiByte(CP_UTF8, 0, wch, -1, utf8buf.data(), len, NULL, NULL); g_pfnErrorCb(utf8buf.data(), code); } }); }关键点pin_ptr在此不可省略因PtrToStringChars返回的指针仅在pin_ptr作用域内有效WideCharToMultiByte确保UTF8编码兼容MFC的char*。5.3 在MFC中注册回调并验证双向通信// MFC中 void CMainFrame::OnOcrProcessWithCallback() { // 注册回调 RegisterCallbacks( [](int percent, const char* status) { // 更新进度条 AfxGetMainWnd()-SetWindowText(CString(_T(OCR )) CString(status)); }, [](const char* message, int code) { // 显示错误 AfxMessageBox(CString(_T(OCR错误)) CString(message)); }); // 调用带回调的版本 int result ProcessImageWithCallback(/*...*/); }这种模式让MFC不再被动等待而是能实时响应C#内部状态。我一般会在C# DLL中封装一个IProgressReporter接口由MFC实现并传入比全局函数指针更易测试——但对遗留MFC系统函数指针仍是最快落地的选择。最后提醒一句混合编程不是银弹。如果项目允许重构建议用现代C20模块化设计将核心算法抽为独立服务HTTP/gRPCMFC只做UI代理。但当你面对一个明天就要交付、客户机器连IE都打不开的现场这套C/CLI桥接方案就是你的后悔药。它不优雅但可靠不前沿但能跑通。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Java汽车4S店管理系统源码实战:Spring Boot+Vue端到端业务闭环

Java汽车4S店管理系统源码实战:Spring Boot+Vue端到端业务闭环

简介:这是一套完整的Java汽车4S店管理系统源码,面向Java Web初学者与中小型汽车服务企业信息化建设者,聚焦销售、售后、库存、客户关系等核心业务场景,提供可直接部署、二次开发的全栈解决方案。资源包共2000个文件,涵…

2026/10/15 0:09:03 阅读更多 →
MATLAB实现MIMO系统广义奈奎斯特曲线:特征轨迹法绘制与稳定性判据

MATLAB实现MIMO系统广义奈奎斯特曲线:特征轨迹法绘制与稳定性判据

简介:一套面向无线通信与自动控制专业学生及研究者的MATLAB工具包,围绕多输入多输出(MIMO)系统广义奈奎斯特(Nyquist)曲线绘制而设计,可用于分析多变量系统的闭环稳定性与奈奎斯特判据在MIMO场景…

2026/10/15 0:09:03 阅读更多 →
openrig实战:用Node.js与tmux搭建稳定的AI编程工作台

openrig实战:用Node.js与tmux搭建稳定的AI编程工作台

1. 从"openrig"这个名字说起:它到底想解决什么问题第一次看到"openrig"这个词,我脑子里蹦出来的不是某个具体软件,而是一种"开放式工作台"的意象。rig在英文里有"装配、搭台、装置"的意思&#xff0…

2026/10/15 0:09:03 阅读更多 →

最新新闻

如何判断Ubuntu是否真的关机?三路检查方法与实战探测脚本

如何判断Ubuntu是否真的关机?三路检查方法与实战探测脚本

你有没有遇到过这种情况:在终端里输入了sudo shutdown now,屏幕上日志飞快滚动,最后一切归于黑暗,风扇也慢慢停转,你很自然地认为这台 Ubuntu 机器已经关机了。但我在几年的实践中发现,这个结论经常下得太早…

2026/10/15 4:25:50 阅读更多 →
企业级升降平台选型指南:基于四大维度的实测横评与采购避坑要点

企业级升降平台选型指南:基于四大维度的实测横评与采购避坑要点

升降平台专业测评做了不少,但企业级采购的选型逻辑和普通短租完全是两码事。这次我们围绕安全、稳定、耐用、综合运维成本四大维度,对市面上主流升降平台做了连续三周的横向测评,最终一家此前不太张扬的厂商凭均衡表现登顶企业级推荐榜&#…

2026/10/15 4:25:50 阅读更多 →
设备资料包处理避坑指南:解压校验、固件版本核对与归档

设备资料包处理避坑指南:解压校验、固件版本核对与归档

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

2026/10/15 4:25:50 阅读更多 →
插件加载失败与SDK版本查询超时:现代工具链插件机制排查指南

插件加载失败与SDK版本查询超时:现代工具链插件机制排查指南

1. 从“plugins”这个标题说起:它到底在聊什么“plugins”这个词,放在今天的开发语境里,早就不只是“插件”两个字那么简单了。你打开任何一个现代开发工具、编辑器、构建系统、甚至云平台的控制台,几乎都会看到它的身影。它背后代…

2026/10/15 4:25:50 阅读更多 →
Windows服务程序调试全攻略:从附加进程到控制台模式与日志排障

Windows服务程序调试全攻略:从附加进程到控制台模式与日志排障

Windows服务程序调试这件事,不少人都被它坑过。初次接触服务开发的人,可能第一反应是把服务项目跑起来、按F5直接进入断点,结果发现根本启动不了。哪怕是工作两三年的开发者,也时常在“服务启动后立刻停止”“日志没输出”“断点死…

2026/10/15 4:25:50 阅读更多 →
AI选品Agent全栈实战:用OpenClaw将跨境电商选品成功率从15%提升到42%

AI选品Agent全栈实战:用OpenClaw将跨境电商选品成功率从15%提升到42%

15%的选品成功率,意味着每选出100个品,最后能跑起来的只有15个,剩下85个全在库存积压和广告费里打水漂。这是跨境电商一个很扎心的平均数——不是某一家团队不行,是整个行业用“人工经验滞后数据”做选品,上限就摆在那…

2026/10/15 4:24:50 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/14 7:53:34 阅读更多 →