利用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;
}
作者:Lighting Cui
出处:http://tugeler.cnblogs.com/
本文版权归作者所,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://tugeler.cnblogs.com/
本文版权归作者所,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号