本项目提供了作业答案解析的两种实现:原生 Python 脚本 (demo.py) 与高性能 Rust 动态链接库 (libresolver.so / resolver.dll 等)。通过 Rust 编译的动态库可以被 Python、C/C++、C#、Java 等其他程序以 FFI 的方式调用。
- Python 3.10+ (支持
match-case语法) - 无需额外第三方依赖(仅使用标准库
os, json, html, logging, time)
- Rust 1.60+
- 依赖:
serde,serde_json
在项目根目录下执行:
cargo build --release编译产物位于 target/release/:
- Windows:
resolver.dll - Android:
libresolver.so - Wasm:
resolver.wasm
在项目根目录下执行:
rustup target add aarch64-linux-android wasm32-unknown-unknown x86_64-pc-windows-msvc
cargo install cargo-ndk
cargo build --target x86_64-pc-windows-msvc --release
cargo build --target wasm32-unknown-unknown --release
cargo ndk --target arm64-v8a build --release编译产物位于 target/release/:
- Windows:
resolver.dll - Android:
libresolver.so - Wasm:
resolver.wasm
直接运行脚本,根据提示输入:
python demo.py通过 Python 的 ctypes 调用 Rust 动态链接库:
import ctypes
import json
lib = ctypes.CDLL("./target/release/libresolver.so")
lib.debug_mode.argtypes = [ctypes.c_bool]
lib.debug_mode.restype = None
lib.nofile_mode.argtypes = [ctypes.c_bool]
lib.nofile_mode.restype = None
lib.resolve.argtypes = [ctypes.c_char_p]
lib.resolve.restype = ctypes.c_void_p
lib.resolver_free_string.argtypes = [ctypes.c_void_p]
lib.resolver_free_string.restype = None
def call(fn, path: str):
ptr = fn(path.encode("utf-8"))
if not ptr:
return None
try:
s = ctypes.cast(ptr, ctypes.c_char_p).value.decode("utf-8")
return json.loads(s)
finally:
lib.resolver_free_string(ptr)
# 1. 路径模式
lib.nofile_mode(False)
print(call(lib.resolve, "./answer"))
# 2. NoFile 模式 (直接传入 JSON 字符串)
lib.nofile_mode(True)
content_json = '{"structure_type": "collector.read", "info": {"stid": "1", "value": "hello", "analyze": "world</br>!"}}'
info_json = "[]"
input_str = json.dumps([content_json, info_json])
print(call(lib.resolve, input_str))注意: cpp引用头文件, 使用resolver.h, 动态链接库和静态链接库在Releases内
- 输入:布尔值,
True开启模式,False关闭。 - 输出:无。需在其他函数调用前先调用此函数配置全局状态。
- 输入:
NOFILE_MODE = False:包含content.json和info.json的文件夹路径。NOFILE_MODE = True:JSON 字符串,格式为"[content.json_str, info.json_str]"。
- 输出:JSON 字符串,解析失败时返回
"null"。解析成功的结构为:
{
"stid1_xth1": {
"answer": ["ans1", "ans2"],
"important": ["keyword1", "keyword2"]
},
"type": "collector.xxx"
}- 输入:
NOFILE_MODE = False:包含多个作业子文件夹的目录路径。NOFILE_MODE = True:JSON 字符串,格式为"[[content1, info1], [content2, info2], ...]"。
- 输出:JSON 字符串,解析失败时返回
"[]"。结构为包含多个resolve返回对象的数组。
- 输入:
NOFILE_MODE = False:包含多个大作业文件夹的总目录路径。NOFILE_MODE = True:JSON 字符串,格式为"[[[c1,i1],[c2,i2]], [[c3,i3], ...], ...]"。
- 输出:JSON 字符串,解析失败时返回
"{}"。结构为以作业名为键、对应作业解析结果(数组)为值的字典。
在项目根目录下执行:
python3 test_demo.py ..\downloaded
python3 test_demo.py ..\downloaded_res
python3 test_lib.py ..\downloaded
python3 test_lib.py ..\downloaded_resPython: 3.14.5
System: Windows 11(25H2,26200.8037)
CPU: AMD(R) Ryzen(TM) 3700X @ 4.3GHz
RAM: G.SKILL Trident Z DDR4 8G*2 3600MHz (Samsung B-DIE)
Disk: WD SN550 1TB
最终汇总:
逐个调用: 14402 成功 / 0 失败 | 23348 答案 | 9.6807s | 2411.81 answers/s
批量调用: 14402 成功 / 0 失败 | 23348 答案 | 5.9476s | 3925.60 answers/s
加速比: 1.63x
最终汇总:
逐个调用: 14402 成功 / 0 失败 | 23348 答案 | 4.3968s | 5310.23 answers/s
批量调用: 14402 成功 / 0 失败 | 23348 答案 | 4.5328s | 5150.93 answers/s
加速比: 0.97x
作者: leitianshuo1337
感谢以下项目的支持:
Rust Programming Language
Python
ETS100
本项目的产生离不开各个开源项目和开源开发者的支持, 向其他开源开发者致敬!