wxocr和mmmojo调用流程

wxocr和mmmojo调用流程
- 文字版执行流程图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132[main()]
│
├─> OcrManager.__init__(wechat_dir)
│ │
│ ├─> 输入:wechat_dir (微信安装目录)
│ ├─> 输出:初始化后的OcrManager实例
│ ├─> 内部流程:
│ │ ├─> platform.architecture() → 判断系统架构
│ │ ├─> os.path.join() → 构造mmmojo_dllpath
│ │ ├─> MmmojoDll.__init__(mmmojo_dllpath)
│ │ │ ├─> CDLL加载DLL文件
│ │ │ └─> init_funcs() 加载28个函数指针
│ │ ├─> Queue(OCR_MAX_TASK_ID) → 初始化任务队列
│ │ └─> m_id_path = {} 初始化任务字典
│ │
├─> SetExePath(wechat_ocr_dir)
│ │
│ ├─> 输入:exe_path (WeChatOCR.exe路径)
│ ├─> 输出:设置self.m_exe_path
│ ├─> 内部检查:
│ │ ├─ if not exe_path.endswith("WeChatOCR.exe") → 自动补全路径
│ │ └─ os.path.exists() 验证路径有效性
│ │
├─> SetUsrLibDir(wechat_dir)
│ │
│ ├─> 输入:usr_lib_dir (微信主程序目录)
│ ├─> 输出:设置self.m_usr_lib_dir
│ ├─> 调用链:
│ │ └─> AppendSwitchNativeCmdLine("user-lib-dir", usr_lib_dir)
│ │ ├─> 输入:arg="user-lib-dir", value=usr_lib_dir
│ │ └─> 输出:self.m_switch_native字典添加条目
│ │
├─> StartWeChatOCR()
│ │
│ ├─> 关键调用链:
│ │ ├─> InitMMMojoEnv()
│ │ │ ├─> self._dll.InitializeMMMojo(0, None)
│ │ │ │ ├─> 输入:argc=0, argv=None
│ │ │ │ └─> 输出:初始化Mojo底层环境
│ │ │ │
│ │ │ ├─> CreateMMMojoEnvironment()
│ │ │ │ ├─> 输入:无
│ │ │ │ └─> 输出:c_void_p环境指针
│ │ │ │
│ │ │ ├─> SetMMMojoEnvironmentCallbacks()
│ │ │ │ ├─> 输入:
│ │ │ │ │ - env_ptr: 环境指针
│ │ │ │ │ - callback_type: kMMUserData
│ │ │ │ │ - py_object(self)
│ │ │ │ └─> 输出:设置用户数据指针
│ │ │ │
│ │ │ ├─> SetDefaultCallbacks()
│ │ │ │ ├─> 遍历MMMojoEnvironmentCallbackType枚举
│ │ │ │ │ └─> 对每个类型设置回调:
│ │ │ │ │ ├─> 获取回调函数地址
│ │ │ │ │ └─> SetMMMojoEnvironmentCallbacks()
│ │ │ │ └─> 输出:完成4个核心回调注册
│ │ │ │
│ │ │ └─> StartMMMojoEnvironment()
│ │ │ ├─> 输入:env_ptr
│ │ │ └─> 输出:启动WeChatOCR.exe子进程
│ │ │
│ ├─> 状态变更:
│ │ └─> m_wechatocr_running = True
│ │
├─> DoOCRTask(pic_path)
│ │
│ ├─> 输入:pic_path (图片路径)
│ ├─> 输出:发送OCR任务到子进程
│ ├─> 详细流程:
│ │ ├─> os.path.abspath() 标准化路径
│ │ ├─> while循环等待m_connect_state.value变为True
│ │ ├─> GetIdleTaskId()
│ │ │ ├─> 从Queue获取可用ID (阻塞1秒)
│ │ │ └─> 返回task_id或None
│ │ ├─> SendOCRTask()
│ │ │ ├─> 构造ocr_protobuf_pb2.OcrRequest对象
│ │ │ │ ├─> task_id分配
│ │ │ │ └─> pic_path添加到pic_paths
│ │ │ ├─> SerializeToString() 序列化
│ │ │ └─> SendPbSerializedData()
│ │ │ ├─> 调用DLL函数:
│ │ │ │ ├─> CreateMMMojoWriteInfo()
│ │ │ │ │ ├─> 输入:method=kMMPush
│ │ │ │ │ └─> 输出:write_info指针
│ │ │ │ │
│ │ │ │ ├─> GetMMMojoWriteInfoRequest()
│ │ │ │ │ ├─> 输入:write_info, pb_size
│ │ │ │ │ └─> 输出:request内存指针
│ │ │ │ │
│ │ │ │ ├─> memmove() 数据拷贝
│ │ │ │ └─> SendMMMojoWriteInfo()
│ │ │ │ ├─> 输入:env_ptr, write_info
│ │ │ │ └─> 输出:发送成功状态
│ │ │ │
│ │ ├─> 记录任务ID到m_id_path字典
│ │
├─> [回调触发] OCRReadOnPush()
│ │
│ ├─> 输入参数:
│ │ - request_id: c_uint32
│ │ - request_info: c_void_p
│ │ - user_data: py_object
│ ├─> 处理流程:
│ │ ├─> GetPbSerializedData()
│ │ │ ├─> 调用DLL函数:
│ │ │ │ └─> GetMMMojoReadInfoRequest()
│ │ │ │ ├─> 输入:request_info指针
│ │ │ │ └─> 输出:pb_data指针和data_size
│ │ │ │
│ │ ├─> 构造ocr_response_ubyte数组
│ │ ├─> ParseFromString() 反序列化Protobuf
│ │ ├─> parse_json_response()
│ │ │ ├─> 输入:json_response_str
│ │ │ └─> 输出:结构化OCR结果字典
│ │ ├─> 调用用户回调ocr_result_callback()
│ │ └─> SetTaskIdIdle() 回收任务ID
│ │
└─> KillWeChatOCR()
│
├─> 关键调用链:
│ ├─> StopMMMojoEnvironment()
│ │ ├─> 输入:env_ptr
│ │ └─> 输出:停止消息循环
│ │
│ ├─> RemoveMMMojoEnvironment()
│ │ ├─> 输入:env_ptr
│ │ └─> 输出:释放环境资源
│ │
│ └─> 状态重置:
│ ├─> m_connect_state.value = False
│ └─> m_wechatocr_running = False