利用SWIG将CTP封装成JAVA版本

重点参考景色大佬文章: 

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

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

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

 

 

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

%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 )

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项目中设置环境变量  

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

 

然后代码中加载库

    static {
        System.loadLibrary("product/thostmduserapi_se");
        System.loadLibrary("product/thosttraderapi_se");
        System.loadLibrary("ctp4java_wrap");
    }

 

调用简单示例:

 

    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中对应方法的响应。

 

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 @ 2022-07-28 10:55  LightingCui  阅读(762)  评论(0编辑  收藏  举报