wxocr和mmmojo调用流程
yaoye Lv5

wxocr和mmmojo调用流程

  1. 文字版执行流程图
    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