跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

基于 SWIG 将 CTP API 封装为 Java SDK

如何在 Windows 环境下,利用 SWIG 工具将 CTP 期货行情交易 API(C++ 库)封装为 Java SDK。主要步骤包括安装 JDK、SWIG 和 Visual Studio,搭建项目目录结构,编写 SWIG 接口文件处理中文编码及回调,生成包装代码,最后使用 Visual Studio 编译生成 JNI 动态链接库,实现 Java 对 CTP 接口的调用。

深海蔚蓝发布于 2026/3/22更新于 2026/7/544 浏览
基于 SWIG 将 CTP API 封装为 Java SDK
前言

新接触的一个项目,需要获取期货的实时报价信息。结合数据来源的权威性和时效性,决定采用 CTP API。CTP API 提供的是 C++ 库,并给出了 Python 实现,因为项目是使用 Java 写的,所以需要自己来编译 C++ 库完成 Java 实现。

一、准备工作

需要安装 CTP API SDK、JDK、SWIG 和 Visual Studio 4 个工具。

1. 下载 CTP API SDK

访问 http://www.openctp.cn/CTPAPI.html,网站提供了 CTP API(期货合约)和 CTP 股票期权 API(股票期权合约)两种接口库,按需选择对应库文件下载。这里下载的是 CTP API ctpapi-6.7.11.zip。

解压 ctpapi-6.7.11.zip 文件,包含以下内容:

其中 v6.7.11_xxx_linux64 是 linux 环境相关文件,v6.7.11_xxx_winApi 是 windows 环境相关文件。因为是在 Win11 环境进行编译和开发,所以选择 winApi 文件夹下的文件。要注意的是,windows 环境的文件区分 32 位和 64 位,目前大多数 windows 操作系统(win10、win11)都是 64 位的,所以要选择 64 位文件,文件名带'64'的是 64 位文件目录。

最终我们需要的文件包括:

  • ThostFtdcMdApi.h:行情 API 头文件
  • ThostFtdcTraderApi.h:交易 API 头文件
  • ThostFtdcUserApiDataType.h:数据类型定义头文件
  • ThostFtdcUserApiStruct.h:数据接口定义头文件
  • thostmduserapi_se.dll:行情动态链接库
  • thostmduserapi_se.lib:行情导入库
  • thosttraderapi_se.dll:交易动态链接库
  • thosttraderapi_se.lib:交易导入库
2. 下载 JDK

访问 https://www.oracle.com/cn/java/technologies/downloads/ 下载 JDK,根据自己的需求选择对应版本,尽量选择 JDK 8+。安装步骤参考网上其他教程。我安装的目录是 D:\Program Files\Java\jdk-8,记住这个路径后面会用到。

3. 下载编译工具 SWIG

访问 https://sourceforge.net/projects/swig/files/,下载 swigwin,这里以 swigwin-4.4.0 为例,下载 zip 包后解压到指定目录,例如 D:\develop\swigwin-4.4.0,然后配置环境变量(Path)。

打开终端,输入 swig -version,看到版本信息说明安装配置成功。

4. 安装 Visual Studio

访问 https://visualstudio.microsoft.com/zh-hans/downloads/,下载 Visual Studio,我下载的是 Visual Studio 2022 Community。注意,选择 Visual Studio,而不是 Visual Studio Code!!!安装时勾选 '桌面开发用 C++'(确保包含 MSVC 编译器、Windows SDK),后续安装和配置步骤可参考网上相关教程。

二、编译步骤
第一步:文件目录结构搭建

新建一个文件夹并重新命名,目录和文件夹名称尽量不要有空格和中文,比如我创建的文件夹名是 CTP-Java-SDK,路径是 D:\develop\CTP-Java-SDK。在该目录下再新建 ctp_lib 目录,将 ctpapi-6.7.11.zip 中解压出来的 8 个头文件和库文件全部复制到此目录中;在 ctp_lib 同级目录下新建 swig 目录,从 swig 的安装目录 swigwin-4.4.0\Lib\java\ 下复制 various.i 文件到此目录中,再手动创建一个 ctp.i 的空文件(swig 接口文件,后面会用到);在 ctp_lib 同级目录下新建 src\com\ctp\sdk(存放 java 文件)、wrap(存放 C++ 包装类文件)、vs_project(vs2022 dll 项目目录)和 final(存放最终可用的文件)几个空文件夹。最后的文件目录结构如下:

D:\develop\CTP-Java-SDK
├─ ctp_lib # CTP 原始文件
│ ├─ ThostFtdcMdApi.h
│ ├─ ThostFtdcTraderApi.h
│ ├─ ThostFtdcUserApiDataType.h
│ ├─ ThostFtdcUserApiStruct.h
│ ├─ thostmduserapi_se.lib
│ ├─ thosttraderapi_se.lib
│ ├─ thostmduserapi_se.dll
│ └─ thosttraderapi_se.dll
├─ swig # SWIG 相关文件
│ ├─ ctp.i # SWIG 接口文件
│ └─ various.i # 从 SWIG 安装目录复制
├─ src # 生成的 Java 类(自动生成)
│ └─ com
│   └─ ctp
│     └─ sdk
├─ wrap # 生成的 C++ 包装代码(自动生成)
├─ vs_project # VS2022 DLL 项目(后续创建)
└─ final # 最终生成的文件
第二步:编写 SWIG 接口文件(ctp.i)

使用 notepad++ 或系统自带的文本编辑器打开 ctp.i 文件,填写下面的内容,如果上面的文件目录和我一样,可直接复制这段 C++ 代码,也可以自行修改:

%module(directors="1") CTPJava // 生成的 Java 类前缀(最终 Java 类名:CTPJavaXXX),可自定义
%include "various.i" // 处理数组参数(订阅合约用)
// 映射 char**为 Java 字符串数组(适配 CTP 订阅合约接口)
%apply char **STRING_ARRAY { char *ppInstrumentID[] }
%{
    // 1. 引入 CTP 头文件,注意改为实际路径
    #include "../ctp_lib/ThostFtdcMdApi.h"
    #include "../ctp_lib/ThostFtdcTraderApi.h"
    #include "../ctp_lib/ThostFtdcUserApiDataType.h"
    #include "../ctp_lib/ThostFtdcUserApiStruct.h"
    // 2. 中文乱码转换(使用 Windows API,兼容 VS2022)
    #include <windows.h>
    #include <string>
    using namespace std;
    // GB2312 转 UTF-8(Windows API 实现,兼容所有 VS 版本)
    string GB2312ToUTF8(const char* gb2312_str) {
        if (gb2312_str == nullptr || *gb2312_str == '\0') {
            return "";
        }
        // 第一步:GB2312 转宽字符(WCHAR)
        int wchar_len = MultiByteToWideChar(
            CP_ACP, // GB2312 编码(CP_ACP 对应系统默认 ANSI 编码,Windows 下即 GB2312)
            0, // 转换选项
            gb2312_str, // 输入 GB2312 字符串
            -1, // 自动计算长度(包含结束符)
            nullptr, // 输出缓冲区(先获取长度)
            0 // 输出缓冲区大小(0 表示仅获取长度)
        );
        WCHAR* wchar_buf = new WCHAR[wchar_len];
        MultiByteToWideChar(CP_ACP, 0, gb2312_str, -1, wchar_buf, wchar_len);
        // 第二步:宽字符转 UTF-8
        int utf8_len = WideCharToMultiByte(
            CP_UTF8, // 目标编码 UTF-8
            0, // 转换选项
            wchar_buf, // 输入宽字符
            -1, // 自动计算长度
            nullptr, // 输出缓冲区(先获取长度)
            0, // 输出缓冲区大小(0 表示仅获取长度)
            nullptr, // 无效字符替换(默认)
            nullptr // 是否使用替换字符(默认)
        );
        char* utf8_buf = new char[utf8_len];
        WideCharToMultiByte(CP_UTF8, 0, wchar_buf, -1, utf8_buf, utf8_len, nullptr, nullptr);
        // 生成结果并释放内存
        string utf8_str(utf8_buf);
        delete[] wchar_buf;
        delete[] utf8_buf;
        return utf8_str;
    }
%}
// 中文编码 GB2312ToUTF8
%typemap(out) char[], char[ANY] {
    string utf8_str = GB2312ToUTF8($1);
    $result = JCALL1(NewStringUTF, jenv, utf8_str.c_str());
}
// 允许 Java 继承 CTP 的 Spi 回调类,并让 C++ 层能反向调用 Java 重写的方法(实现回调逻辑)
%feature("director") CThostFtdcMdSpi;
%feature("director") CThostFtdcTraderSpi;
// 测试时发现没有自动触发 OnRtnDepthMarketData() 方法,所以这里显式声明一下,确保 SWIG 识别并生成转发代码)
%extend CThostFtdcMdSpi {
    // 显式声明 OnRtnDepthMarketData 回调(与 CTP 头文件签名一致)
    virtual void OnRtnDepthMarketData(const CThostFtdcDepthMarketDataField* pDepthMarketData) {}
}
// 忽略 CTP 冗余常量(避免编译冲突)
%ignore THOST_FTDC_VTC_BankBankToFuture;
%ignore THOST_FTDC_VTC_BankFutureToBank;
%ignore THOST_FTDC_VTC_FutureBankToFuture;
%ignore THOST_FTDC_VTC_FutureFutureToBank;
%ignore THOST_FTDC_FTC_BankLaunchBankToBroker;
%ignore THOST_FTDC_FTC_BrokerLaunchBankToBroker;
%ignore THOST_FTDC_FTC_BankLaunchBrokerToBank;
%ignore THOST_FTDC_FTC_BrokerLaunchBrokerToBank;
// 引入 CTP 结构体和接口(顺序必须:先数据类型,后 API)
%include "../ctp_lib/ThostFtdcUserApiDataType.h" // 结构体类型
%include "../ctp_lib/ThostFtdcUserApiStruct.h" // 结构体定义
%include "../ctp_lib/ThostFtdcMdApi.h" // 行情接口(包含 MdSpi 所有回调)
%include "../ctp_lib/ThostFtdcTraderApi.h" // 交易接口(包含 TraderSpi 所有回调)
第三步:用 SWIG 生成包装代码

打开命令提示符(管理员模式),进入 D:\develop\CTP-Java-SDK\swig,执行以下命令:

swig -c++ -java -package com.ctp.sdk -outdir ../src/com/ctp/sdk -o ../wrap/ctp_wrap.cpp ctp.i 
  • 参数说明:
    • -c++:处理 C++ 代码;
    • -java:生成 Java 绑定;
    • -package com.ctp.sdk:Java 类的包名(后续导入需用),可自定义;
    • -outdir ../src/com/ctp/sdk:Java 类输出到 src/com/ctp/sdk 目录;
    • -o ../wrap/ctp_wrap.cpp:C++ 包装代码输出到 wrap 目录;

如果没有报错(两个警告不用管),此时 src/com/ctp/sdk 目录中已生成 java 文件(我生成的是 510 个.java 文件);D:\develop\CTP-Java-SDK\wrap 目录下生成 C++ 包装代码文件。

第四步:用 VS2022 编译 JNI 动态库
4.1 新建 VS DLL 项目
  1. 打开 VS2022,点击 '创建新项目';
  2. 搜索 '动态链接库 (DLL)',选择 'C++' 模板,命名为 CTPJavaDLL,保存到 D:\develop\CTP_Java_SDK\vs_project;

勾选'将解决方案和项目放在同一目录中',点击 '创建'。

4.2 添加文件到项目

在 VS2022 顶部工具栏中将 Debug 改为 Release。

  • 鼠标右键项目 → '添加' → '现有项':
    • 添加 D:\develop\CTP_Java_SDK\wrap\ctp_wrap.cpp(C++ 包装代码);
    • 添加 D:\develop\CTP_Java_SDK\ctp_lib 下的所有 .h 头文件。

添加成功后,项目头文件和源文件会显示添加的文件。

4.3 配置项目属性(关键)

右键项目→属性

目录

  1. 前言
  2. 一、准备工作
  3. 1. 下载 CTP API SDK
  4. 2. 下载 JDK
  5. 3. 下载编译工具 SWIG
  6. 4. 安装 Visual Studio
  7. 二、编译步骤
  8. 第一步:文件目录结构搭建
  9. 第二步:编写 SWIG 接口文件(ctp.i)
  10. 第三步:用 SWIG 生成包装代码
  11. 第四步:用 VS2022 编译 JNI 动态库
  12. 4.1 新建 VS DLL 项目
  13. 4.2 添加文件到项目
  14. 4.3 配置项目属性(关键)
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 前端组件库:拒绝重复造轮子,提升开发效率
  • 算法:双指针法详解(上)
  • Python 屏幕截图翻译工具实战
  • 字节前端一面面经解析:网络原理、Vue 及手写题详解
  • 6 层高速 PCB 设计实战:逻辑派 FPGA-G1 开发板布局布线详解
  • 前端权限管理实现方案与最佳实践
  • 区块链共识算法:时间长河(Time River Consensus Algorithm)
  • 无人机视角山区泥石流和滑坡图像识别数据集
  • 基于人类反馈的强化学习(RLHF)全解析
  • Ubuntu Edgy Eft 完整软件源列表配置指南
  • 文心大模型 4.5 开源部署实战与中文场景应用
  • Python 语音识别结合 Appium 实现抖音自动化操作
  • HarmonyOS 底部导航栏组件 rc_concave_tabbar 使用指南
  • Android WebView 开发指南:AgentWeb 完整使用
  • 从 AI 绘图到 AI 视频:2026 内容创作者进阶之路
  • ERNIE-4.5-VL-28B-A3B-Paddle 与 DeepSeek-R1 多维度测评分析
  • 利用文心一言为智能体设计稳定的工作流提示词
  • 前端国际化最佳实践与实现方案
  • 基于 Coze 构建专属 AI 应用:从智能体开发到 Web 部署实战
  • Python 零基础学习指南

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online