<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>开发 on 空山寻痕</title>
    <link>https://kongseek.com/categories/%E5%BC%80%E5%8F%91/</link>
    <description>Recent content in 开发 on 空山寻痕</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Wed, 09 Sep 2026 00:26:37 +0800</lastBuildDate>
    <atom:link href="https://kongseek.com/categories/%E5%BC%80%E5%8F%91/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>wxocr和mmmojo调用流程</title>
      <link>https://kongseek.com/wxocr%E5%92%8Cmmmojo%E8%B0%83%E7%94%A8%E6%B5%81%E7%A8%8B/</link>
      <pubDate>Wed, 09 Sep 2026 00:24:21 +0800</pubDate>
      <guid>https://kongseek.com/wxocr%E5%92%8Cmmmojo%E8%B0%83%E7%94%A8%E6%B5%81%E7%A8%8B/</guid>
      <description>&lt;ol&gt;&#xA;&lt;li&gt;文字版执行流程图&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[main()]&#xA;│&#xA;├─&amp;gt; OcrManager.__init__(wechat_dir)&#xA;│    │&#xA;│    ├─&amp;gt; 输入：wechat_dir (微信安装目录)&#xA;│    ├─&amp;gt; 输出：初始化后的OcrManager实例&#xA;│    ├─&amp;gt; 内部流程：&#xA;│    │   ├─&amp;gt; platform.architecture() → 判断系统架构&#xA;│    │   ├─&amp;gt; os.path.join() → 构造mmmojo_dllpath&#xA;│    │   ├─&amp;gt; MmmojoDll.__init__(mmmojo_dllpath)&#xA;│    │   │    ├─&amp;gt; CDLL加载DLL文件&#xA;│    │   │    └─&amp;gt; init_funcs() 加载28个函数指针&#xA;│    │   ├─&amp;gt; Queue(OCR_MAX_TASK_ID) → 初始化任务队列&#xA;│    │   └─&amp;gt; m_id_path = {} 初始化任务字典&#xA;│    │&#xA;├─&amp;gt; SetExePath(wechat_ocr_dir)&#xA;│    │&#xA;│    ├─&amp;gt; 输入：exe_path (WeChatOCR.exe路径)&#xA;│    ├─&amp;gt; 输出：设置self.m_exe_path&#xA;│    ├─&amp;gt; 内部检查：&#xA;│    │   ├─ if not exe_path.endswith(&amp;#34;WeChatOCR.exe&amp;#34;) → 自动补全路径&#xA;│    │   └─ os.path.exists() 验证路径有效性&#xA;│    │&#xA;├─&amp;gt; SetUsrLibDir(wechat_dir)&#xA;│    │&#xA;│    ├─&amp;gt; 输入：usr_lib_dir (微信主程序目录)&#xA;│    ├─&amp;gt; 输出：设置self.m_usr_lib_dir&#xA;│    ├─&amp;gt; 调用链：&#xA;│    │   └─&amp;gt; AppendSwitchNativeCmdLine(&amp;#34;user-lib-dir&amp;#34;, usr_lib_dir)&#xA;│    │       ├─&amp;gt; 输入：arg=&amp;#34;user-lib-dir&amp;#34;, value=usr_lib_dir&#xA;│    │       └─&amp;gt; 输出：self.m_switch_native字典添加条目&#xA;│    │&#xA;├─&amp;gt; StartWeChatOCR()&#xA;│    │&#xA;│    ├─&amp;gt; 关键调用链：&#xA;│    │   ├─&amp;gt; InitMMMojoEnv()&#xA;│    │   │    ├─&amp;gt; self._dll.InitializeMMMojo(0, None)&#xA;│    │   │    │    ├─&amp;gt; 输入：argc=0, argv=None&#xA;│    │   │    │    └─&amp;gt; 输出：初始化Mojo底层环境&#xA;│    │   │    │&#xA;│    │   │    ├─&amp;gt; CreateMMMojoEnvironment()&#xA;│    │   │    │    ├─&amp;gt; 输入：无&#xA;│    │   │    │    └─&amp;gt; 输出：c_void_p环境指针&#xA;│    │   │    │&#xA;│    │   │    ├─&amp;gt; SetMMMojoEnvironmentCallbacks()&#xA;│    │   │    │    ├─&amp;gt; 输入：&#xA;│    │   │    │    │   - env_ptr: 环境指针&#xA;│    │   │    │    │   - callback_type: kMMUserData&#xA;│    │   │    │    │   - py_object(self)&#xA;│    │   │    │    └─&amp;gt; 输出：设置用户数据指针&#xA;│    │   │    │&#xA;│    │   │    ├─&amp;gt; SetDefaultCallbacks()&#xA;│    │   │    │    ├─&amp;gt; 遍历MMMojoEnvironmentCallbackType枚举&#xA;│    │   │    │    │   └─&amp;gt; 对每个类型设置回调：&#xA;│    │   │    │    │       ├─&amp;gt; 获取回调函数地址&#xA;│    │   │    │    │       └─&amp;gt; SetMMMojoEnvironmentCallbacks()&#xA;│    │   │    │    └─&amp;gt; 输出：完成4个核心回调注册&#xA;│    │   │    │&#xA;│    │   │    └─&amp;gt; StartMMMojoEnvironment()&#xA;│    │   │         ├─&amp;gt; 输入：env_ptr&#xA;│    │   │         └─&amp;gt; 输出：启动WeChatOCR.exe子进程&#xA;│    │   │&#xA;│    ├─&amp;gt; 状态变更：&#xA;│    │   └─&amp;gt; m_wechatocr_running = True&#xA;│    │&#xA;├─&amp;gt; DoOCRTask(pic_path)&#xA;│    │&#xA;│    ├─&amp;gt; 输入：pic_path (图片路径)&#xA;│    ├─&amp;gt; 输出：发送OCR任务到子进程&#xA;│    ├─&amp;gt; 详细流程：&#xA;│    │   ├─&amp;gt; os.path.abspath() 标准化路径&#xA;│    │   ├─&amp;gt; while循环等待m_connect_state.value变为True&#xA;│    │   ├─&amp;gt; GetIdleTaskId()&#xA;│    │   │    ├─&amp;gt; 从Queue获取可用ID (阻塞1秒)&#xA;│    │   │    └─&amp;gt; 返回task_id或None&#xA;│    │   ├─&amp;gt; SendOCRTask()&#xA;│    │   │    ├─&amp;gt; 构造ocr_protobuf_pb2.OcrRequest对象&#xA;│    │   │    │    ├─&amp;gt; task_id分配&#xA;│    │   │    │    └─&amp;gt; pic_path添加到pic_paths&#xA;│    │   │    ├─&amp;gt; SerializeToString() 序列化&#xA;│    │   │    └─&amp;gt; SendPbSerializedData()&#xA;│    │   │         ├─&amp;gt; 调用DLL函数：&#xA;│    │   │         │   ├─&amp;gt; CreateMMMojoWriteInfo()&#xA;│    │   │         │   │    ├─&amp;gt; 输入：method=kMMPush&#xA;│    │   │         │   │    └─&amp;gt; 输出：write_info指针&#xA;│    │   │         │   │&#xA;│    │   │         │   ├─&amp;gt; GetMMMojoWriteInfoRequest()&#xA;│    │   │         │   │    ├─&amp;gt; 输入：write_info, pb_size&#xA;│    │   │         │   │    └─&amp;gt; 输出：request内存指针&#xA;│    │   │         │   │&#xA;│    │   │         │   ├─&amp;gt; memmove() 数据拷贝&#xA;│    │   │         │   └─&amp;gt; SendMMMojoWriteInfo()&#xA;│    │   │         │        ├─&amp;gt; 输入：env_ptr, write_info&#xA;│    │   │         │        └─&amp;gt; 输出：发送成功状态&#xA;│    │   │         │&#xA;│    │   ├─&amp;gt; 记录任务ID到m_id_path字典&#xA;│    │&#xA;├─&amp;gt; [回调触发] OCRReadOnPush()&#xA;│    │&#xA;│    ├─&amp;gt; 输入参数：&#xA;│    │   - request_id: c_uint32&#xA;│    │   - request_info: c_void_p&#xA;│    │   - user_data: py_object&#xA;│    ├─&amp;gt; 处理流程：&#xA;│    │   ├─&amp;gt; GetPbSerializedData()&#xA;│    │   │    ├─&amp;gt; 调用DLL函数：&#xA;│    │   │    │   └─&amp;gt; GetMMMojoReadInfoRequest()&#xA;│    │   │    │        ├─&amp;gt; 输入：request_info指针&#xA;│    │   │    │        └─&amp;gt; 输出：pb_data指针和data_size&#xA;│    │   │    │&#xA;│    │   ├─&amp;gt; 构造ocr_response_ubyte数组&#xA;│    │   ├─&amp;gt; ParseFromString() 反序列化Protobuf&#xA;│    │   ├─&amp;gt; parse_json_response()&#xA;│    │   │    ├─&amp;gt; 输入：json_response_str&#xA;│    │   │    └─&amp;gt; 输出：结构化OCR结果字典&#xA;│    │   ├─&amp;gt; 调用用户回调ocr_result_callback()&#xA;│    │   └─&amp;gt; SetTaskIdIdle() 回收任务ID&#xA;│    │&#xA;└─&amp;gt; KillWeChatOCR()&#xA;     │&#xA;     ├─&amp;gt; 关键调用链：&#xA;     │   ├─&amp;gt; StopMMMojoEnvironment()&#xA;     │   │    ├─&amp;gt; 输入：env_ptr&#xA;     │   │    └─&amp;gt; 输出：停止消息循环&#xA;     │   │&#xA;     │   ├─&amp;gt; RemoveMMMojoEnvironment()&#xA;     │   │    ├─&amp;gt; 输入：env_ptr&#xA;     │   │    └─&amp;gt; 输出：释放环境资源&#xA;     │   │&#xA;     │   └─&amp;gt; 状态重置：&#xA;     │       ├─&amp;gt; m_connect_state.value = False&#xA;     │       └─&amp;gt; m_wechatocr_running = False&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
  </channel>
</rss>
