ctp-rs
CTP 期货接口的安全、符合 Rust 惯用法的绑定。支持 Windows、Linux 与 macOS 三平台。
Safe & idiomatic Rust bindings for CTP — cross-platform (Windows / Linux / macOS).
特性
- 跨平台:支持 Windows、Linux(x86_64)与 macOS(Apple Silicon / x86_64)
- 安全 API:所有接口均采用 Rust 字符串与所有权语义,字符串编码自动转换,消除 C++ 裸指针风险
- 基于 channel 的消息传递:SPI 回调通过标准库
mpsc::channel传递,可与异步运行时或多线程程序无缝集成
快速开始
可直接从 crates.io 安装:
发布在 crates.io 的包采用 SemVer 版本号系统。
底层绑定的 CTP C++ 版本号被包含在 build meta 中,如 0.2.1+ctp.6.7.11.darwin.6.7.7:Windows/Linux 跟随上游,macOS 使用上游目前最新的 darwin SDK。
示例
1. 行情接口(MdApi)
use ;
use ;
// 模拟环境地址列表见:http://www.openctp.cn/simenv.html
const FRONT_ADDR: &str = "tcp://...";
const FLOW_PATH: &str = "MdFlow/";
const INSTRUMENTS: & = &;
2. 交易接口(TraderApi)
use ;
use ;
const BROKER_ID: &str = "...";
const USER_ID: &str = "...";
const PASSWORD: &str = "...";
const APP_ID: &str = "...";
const AUTH_CODE: &str = "...";
const FRONT_ADDR: &str = "tcp://...";
const FLOW_PATH: &str = "TraderFlow/";
平台行为
三平台均使用预编译的真实 CTP 动态库。Windows/Linux 是 .dll/.so,与可执行文件并排部署;macOS 是嵌入到二进制中的 framework dylib,详见下方 macOS framework 处理。
注意事项
CTP 回报中的空指针
- CTP 返回空指针时,对应 Field 结构体的
is_null字段会为true。
字符串编码
-
大部分接口实现了字符串自动编码转换,可在 Rust 中直接使用
String。
少部分字段(如结算单)因 CTP 截断汉字导致编码转换失败,这些字段保留为Vec<u8>。如需打印含中文的
Vec<u8>字段,可使用encoding_rs:use GBK; let contents = GBK.decode.0.to_string;
构建要求
CTP 原生库(headers + macOS framework + Windows .dll/.lib + Linux .so)超过了 crates.io 的压缩包体积限制,因此不随 crate 发布。build.rs 在第一次构建时会从 Cloudflare R2 下载并解压到 $OUT_DIR/lib/,同一 OUT_DIR 内的后续构建直接复用($OUT_DIR 是按 target/profile/构建脚本哈希区分的,如需强制重新下载,cargo clean 即可)。
下载源(约 12 MB):
为避免引入额外的 Rust HTTP/zip 构建依赖(多 MB 编译开销,且无法保留 macOS framework 内部的符号链接),build.rs 直接调用系统工具完成下载与解压。首次构建机器需具备:
| 平台 | 必需 | 备注 |
|---|---|---|
| macOS | curl、unzip |
系统自带,无需额外安装 |
| Linux | curl、unzip |
大部分发行版自带;最小镜像(如 ubuntu:*-slim、debian:*-slim)需 apt-get install -y curl unzip |
| Windows | curl.exe、tar.exe |
Windows 10 1803+(2018 年 4 月)/ Windows Server 2019+ 自带 |
构建机器必须可访问 ctp-api.ruiqilei.com。
macOS framework 处理
macOS 平台的真实 CTP 由 $OUT_DIR/lib/darwin/ 下的 thostmduserapi_se.framework 与 thosttraderapi_se.framework 提供(darwin 6.7.7,由 build.rs 解压到 OUT_DIR)。这两个 framework 的处理方式与 Windows/Linux 上的 .dll/.so 不同:
- 构建期嵌入:
build.rs把两个 framework 内部的 dylib 字节通过.incbin拼进__DATA,__const段,最终二进制是自包含的——不需要把任何 dylib 与可执行文件一起分发。 - 运行期
dlopen:第一次调用 MdApi/TraderApi 时,会把嵌入的字节写到$TMPDIR/ctp-rs.<pid>.<name>.dylib,再用RTLD_NOW | RTLD_LOCAL打开。CreateFtdcMdApi/CreateFtdcTraderApi/GetApiVersion通过dlsym拿到,其余方法均为虚函数,走 framework 自带的 vtable。 - 临时再签名:Gatekeeper 不允许从任意路径
dlopen。build.rs会在构建时调用codesign --remove-signature后再codesign --sign -做 ad-hoc 签名,最终用户机器上无需再做任何签名操作。 - darwin SDK 与 Linux/Windows 不一致:上游目前 macOS 仅发布到 6.7.7,Linux/Windows 已是 6.7.11。两者的 wire protocol 兼容,但极个别字段或常量可能不同;行为差异请参考 zip 包内
darwin/thostmduserapi_se.framework/Versions/A/Headers/下的实际头文件(解压后位于$OUT_DIR/lib/darwin/...)。 - CreateFtdcXxxApi 签名差异:darwin 的
CreateFtdcMdApi/CreateFtdcTraderApi比 Linux 头文件少一个bIsProductionMode参数,wrapper 内部已自动桥接,对 Rust 侧完全透明。