利用SWIG将CTP封装成JAVA版本

重点参考景色大佬文章: 

 CTP JAVA API(JCTP)编译(利用Swig封装C++动态库)windows版_景色正好的博客-CSDN博客

 Swig转换C++接口中文乱码解决方案_景色正好的博客-CSDN博客

其中第二篇文章里,直接用文中给出的i修改方式会报错,原因在文章的评论区。

 

 

最后可用的 .i 文件全文如下:(将市场接口和行情接口打包到一个jar中)

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
%module(directors="1") CTP4Java
%include "various.i"
%apply char **STRING_ARRAY { char *ppInstrumentID[] }
 
 
%{
#include "ThostFtdcMdApi.h"
#include "ThostFtdcTraderApi.h"
 
#include <codecvt>
#include <locale>
#include <vector>
#include <string>
using namespace std;
#ifdef _MSC_VER
const static locale g_loc("zh-CN");
#else   
const static locale g_loc("zh_CN.GB18030");
#endif
%}
  
 
%typemap(out) char[ANY], char[] {
    const std::string &gb2312($1);
    std::vector<wchar_t> wstr(gb2312.size());
    wchar_t* wstrEnd = nullptr;
    const char* gbEnd = nullptr;
    mbstate_t state = {};
    int res = use_facet<codecvt<wchar_t, char, mbstate_t> >
        (g_loc).in(state,
            gb2312.data(), gb2312.data() + gb2312.size(), gbEnd,
            wstr.data(), wstr.data() + wstr.size(), wstrEnd);
  
    if (codecvt_base::ok == res)
    {
        wstring_convert<codecvt_utf8<wchar_t>> cutf8;
        std::string result = cutf8.to_bytes(wstring(wstr.data(), wstrEnd));      
        $result=JCALL1(NewStringUTF,jenv,result.c_str());    }
    else
    {
        std::string result;
        $result=JCALL1(NewStringUTF,jenv,result.c_str());    }
}
 
%feature("director") CThostFtdcMdSpi;
%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;
%include "ThostFtdcUserApiDataType.h"
%include "ThostFtdcUserApiStruct.h"
%include "ThostFtdcMdApi.h"
%feature("director") CThostFtdcTraderSpi;
%include "ThostFtdcTraderApi.h"

 

various.i 在swig安装目录中找到(如: D:\swig\swigwin-4.0.2\Lib\java)

 

命令如下:

( swig命令生成 ctp4java_wrap.h 和 ctp4java_wrap.cpp  jar 命令打包成 ctp4java.jar )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mkdir src
 
mkdir -p com/tugeler/ctp4java/v6_6_1
 
swig.exe -c++ -java -package com.tugeler.ctp4java.v6_6_1 -outdir src -o ctp4java_wrap.cpp ctp4java.i 
  
cd .\src\
  
javac *.java
  
cd ..
  
mv src/*.class .\com\tugeler\ctp4java\v6_6_1
  
jar.exe cf ctp4java.jar com

  

 

 项目结构:

 

JAVA项目中设置环境变量  

1
-Djava.library.path=$ProjectFileDir$/lib

 

然后代码中加载库

1
2
3
4
5
static {
    System.loadLibrary("product/thostmduserapi_se");
    System.loadLibrary("product/thosttraderapi_se");
    System.loadLibrary("ctp4java_wrap");
}

 

调用简单示例:

 

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
    CThostFtdcTraderApi api = CThostFtdcTraderApi.CreateFtdcTraderApi();
    TraderSpiImpl spi = new TraderSpiImpl(api);
    api.RegisterSpi(spi);
    api.RegisterFront("tcp://111.222.333.444:56789");
    api.SubscribePublicTopic(THOST_TE_RESUME_TYPE.THOST_TERT_RESTART);
    api.SubscribePrivateTopic(THOST_TE_RESUME_TYPE.THOST_TERT_RESTART);
    api.Init();
    api.Join();
    api.Release();
    return;
}

 

其中 SPI 是自己写的继承 CThostFtdcTraderSpi 后复写API中对应方法的响应。

 

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
class TraderSpiImpl extends CThostFtdcTraderSpi {
    final static String m_BrokerId = "xxxxx";
    final static String m_UserId = "xxxxx";
    final static String m_InvestorId = "xxxxx";
    final static String m_AccountId = "xxxxx";
    final static String m_appID = "xxxxx";
    final static String m_appCode = "xxxxx";
    final static String m_PassWord = "xxxxx";
    private List<String> ListExchanges = new ArrayList<String>();
    private List<String> ListProducts = new ArrayList<String>();
    private List<String> ListInstruments = new ArrayList<String>();
    TraderSpiImpl(CThostFtdcTraderApi traderapi) {
        m_traderapi = traderapi;
    }
    @Override
    public void OnFrontConnected() {
        System.out.println("On Front Connected");
        CThostFtdcReqAuthenticateField clientAuth = new CThostFtdcReqAuthenticateField();
        clientAuth.setBrokerID(m_BrokerId);
        clientAuth.setUserID(m_UserId);
        clientAuth.setAppID(m_appID);
        clientAuth.setAuthCode(m_appCode);
        clientAuth.setUserProductInfo(m_appID);
        int b = m_traderapi.ReqAuthenticate(clientAuth, 0);
        System.out.println("b:" + b);
        System.out.println("Send auth ok");
    }
 
    @Override
    public void OnRspAuthenticate(CThostFtdcRspAuthenticateField field, CThostFtdcRspInfoField pRspInfo,
                               int nRequestID, boolean bIsLast) {
        if (pRspInfo != null && pRspInfo.getErrorID() != 0) {
            System.out.printf("Auth ErrorID[%d] ErrMsg[%s]\n", pRspInfo.getErrorID(), pRspInfo.getErrorMsg());
            return;
        }
        System.out.println("Auth success!!!");
        CThostFtdcReqUserLoginField userLogin = new CThostFtdcReqUserLoginField();
        userLogin.setBrokerID(m_BrokerId);
        userLogin.setUserID(m_UserId);
        userLogin.setPassword(m_PassWord);
        userLogin.setUserProductInfo("JAVA_API");
        int a = m_traderapi.ReqUserLogin(userLogin, 1);
        System.out.println("a:" + a);
        System.out.println("Send login ok");
    }
    @Override
    public void OnRspUserLogin(CThostFtdcRspUserLoginField pRspUserLogin, CThostFtdcRspInfoField pRspInfo,
                               int nRequestID, boolean bIsLast) {
        if (pRspInfo != null && pRspInfo.getErrorID() != 0) {
            System.out.printf("Login ErrorID[%d] ErrMsg[%s]\n", pRspInfo.getErrorID(), pRspInfo.getErrorMsg());
            return;
        }
        System.out.println(pRspUserLogin);
        System.out.println("Login success!!!");
        CThostFtdcQryExchangeField pQryExchange = new CThostFtdcQryExchangeField();
        int b = m_traderapi.ReqQryExchange(pQryExchange, 1);
        System.out.println("b:" + b);
    }
    @Override
    public void OnRspQryExchange(CThostFtdcExchangeField pExchange, CThostFtdcRspInfoField pRspInfo, int nRequestID,
                                 boolean bIsLast) {
        System.out.println(bIsLast + " : " +JSON.toJSONString(pExchange));
        ListExchanges.add(pExchange.toString());
        if (bIsLast) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            CThostFtdcQryProductField pQryProduct = new CThostFtdcQryProductField();
            int c = m_traderapi.ReqQryProduct(pQryProduct, 2);
        }
    }
    @Override
    public void OnRspQryProduct(CThostFtdcProductField pProduct, CThostFtdcRspInfoField pRspInfo, int nRequestID,
                                boolean bIsLast) {
        System.out.println(bIsLast + " : " +JSON.toJSONString(pProduct));
        ListProducts.add(pProduct.toString());
        if(bIsLast) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            CThostFtdcQryInstrumentField pQryInstrument = new CThostFtdcQryInstrumentField();
            int d = m_traderapi.ReqQryInstrument(pQryInstrument, nRequestID);
            System.out.println("d:"+d);
        }
    }
    @Override
    public void OnRspQryInstrument(CThostFtdcInstrumentField pInstrument, CThostFtdcRspInfoField pRspInfo,
                                   int nRequestID, boolean bIsLast) {
        System.out.println(bIsLast + " : " +JSON.toJSONString(pInstrument));
        ListInstruments.add(pInstrument.toString());
    }
    private CThostFtdcTraderApi m_traderapi;
}

  

 

  

 

posted @   LightingCui  阅读(999)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示