CTP 订阅全市场行情-交易---栗子 C APi转 java Api版本

前言
本文 介绍 利用Swig工具将CTP C++接口API转换为Java可调用的接口
整合订阅全市场合约traderapi(交易)和订阅全市场合约mdapi(行情)demo
但是由于CTP只提供了对C++版本的API接口 那现在作为java开发就很难受了 ,那我们可不可以将C转为java呢 ,?
当然是可行的,下面就是完整的教程.综合的景大佬的技术支持,
景大佬链接如下:

https://blog.csdn.net/pjjing/article/details/53186394

首先需要的技术支持有:

  • 安装JDK,注意版本要跟你的CTP下载的代码和你工程一致,将环境变量配置好。
  • 安装idea。-这个不过多阐述, 度娘上面很多安装教程.主要用与Java demo的测试,点击下载
  • 安装Swig软件,本文中所用的Swig是swigwin-2.0.11版本,
  • SWIG是一个能将C/C++接口转换为其他语言的工具,目前可以支持Python,Java,R等语言

链接:https://pan.baidu.com/s/1XR3ym5BQgeHxFsCvkP0gJw
提取码:ov63
点击下载。

  • 安装libiconv库。这个库主要适用于字节编码转换,因为CTP的结算单信息是GB2312编码,而Java采用UTF-8编码,如果不
    进行字节转换,得到的结算单信息中的中文将会是乱码。
    本文采用的libiconv版本是自己下载的源码编译的静态库,也可以到我的github libiconv下载编译好的。
    (建议直接用.这边是借用的景大佬的.)

https://github.com/15200001554/libiconv1

  • 安装vs2013,主要用于生成包装dll。

链接:https://pan.baidu.com/s/1I7Wyg9VfLjFOr_pXruHL-Q
提取码:c6lb

首先上海期货信息技术有限公司 下载API
在这里插入图片描述
解压缩进入到
在6.3.15_20190220_tradeapi64_se_windows 包下创建几个空的文件夹
目录结构如下:

6.3.15_20190220_tradeapi64_se_windows
│
│─── ctp ─── thostapi
│
│─── demo
│
│─── src
│
│─── wrap
│
│ ThostFtdcMdApi.h
│ ThostFtdcTraderApi.h
│ ThostFtdcUserApiDataType.h
│ …

在这里插入图片描述
2.通过Swig得到jar包
在当前文件夹内,新建文件thostapi.i,内容如下

%module(directors="1") thosttraderapi 
%include "various.i"
%apply char **STRING_ARRAY { char *ppInstrumentID[] }
%{ 
#include "ThostFtdcMdApi.h"
#include "ThostFtdcTraderApi.h"
#include "iconv.h"
%}

%typemap(out) char[ANY], char[] {
    if ($1) {
        iconv_t cd = iconv_open("utf-8", "gb2312");
        if (cd != reinterpret_cast<iconv_t>(-1)) {
            char buf[4096] = {};
            char **in = &$1;
            char *out = buf;
            size_t inlen = strlen($1), outlen = 4096;

            if (iconv(cd, in, &inlen, &out, &outlen) != static_cast<size_t>(-1))
                $result = JCALL1(NewStringUTF, jenv, (const char *)buf);
            iconv_close(cd);
        }
    }
}

%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自带的,将swig/Lib/java/various.i拷贝过来即可。

/* -----------------------------------------------------------------------------
 * various.i
 *
 * SWIG Typemap library for Java.
 * Various useful typemaps.
 * ----------------------------------------------------------------------------- */

/* 
 * char **STRING_ARRAY typemaps. 
 * These typemaps are for C String arrays which are NULL terminated.
 *   char *values[] = { "one", "two", "three", NULL }; // note NULL
 * char ** is mapped to a Java String[].
 *
 * Example usage wrapping:
 *   %apply char **STRING_ARRAY { char **input };
 *   char ** foo(char **input);
 *  
 * Java usage:
 *   String numbers[] = { "one", "two", "three" };
 *   String[] ret = modulename.foo( numbers };
 */
%typemap(jni) char **STRING_ARRAY "jobjectArray"
%typemap(jtype) char **STRING_ARRAY "String[]"
%typemap(jstype) char **STRING_ARRAY "String[]"
%typemap(in) char **STRING_ARRAY (jint size) {
  int i = 0;
  if ($input) {
    size = JCALL1(GetArrayLength, jenv, $input);
#ifdef __cplusplus
    $1 = new char*[size+1];
#else
    $1 = (char **)calloc(size+1, sizeof(char *));
#endif
    for (i = 0; i<size; i++) {
      jstring j_string = (jstring)JCALL2(GetObjectArrayElement, jenv, $input, i);
      const char *c_string = JCALL2(GetStringUTFChars, jenv, j_string, 0);
#ifdef __cplusplus
      $1[i] = new char [strlen(c_string)+1];
#else
      $1[i] = (char *)calloc(strlen(c_string)+1, sizeof(const char *));
#endif
      strcpy($1[i], c_string);
      JCALL2(ReleaseStringUTFChars, jenv, j_string, c_string);
      JCALL1(DeleteLocalRef, jenv, j_string);
    }
    $1[i] = 0;
  } else {
    $1 = 0;
    size = 0;
  }
}

%typemap(freearg) char **STRING_ARRAY {
  int i;
  for (i=0; i<size$argnum-1; i++)
#ifdef __cplusplus
    delete[] $1[i];
  delete[] $1;
#else
  free($1[i]);
  free($1);
#endif
}

%typemap(out) char **STRING_ARRAY {
  if ($1) {
    int i;
    int len=0;
    jstring temp_string;
    const jclass clazz = JCALL1(FindClass, jenv, "java/lang/String");

    while ($1[len]) len++;
    $result = JCALL3(NewObjectArray, jenv, len, clazz, NULL);
    /* exception checking omitted */

    for (i=0; i<len; i++) {
      temp_string = JCALL1(NewStringUTF, jenv, *$1++);
      JCALL3(SetObjectArrayElement, jenv, $result, i, temp_string);
      JCALL1(DeleteLocalRef, jenv, temp_string);
    }
  }
}

%typemap(javain) char **STRING_ARRAY "$javainput"
%typemap(javaout) char **STRING_ARRAY {
    return $jnicall;
  }

/* 
 * char **STRING_OUT typemaps. 
 * These are typemaps for returning strings when using a C char ** parameter type.
 * The returned string appears in the 1st element of the passed in Java String array.
 *
 * Example usage wrapping:
 *   void foo(char **string_out);
 *  
 * Java usage:
 *   String stringOutArray[] = { "" };
 *   modulename.foo(stringOutArray);
 *   System.out.println( stringOutArray[0] );
 */
%typemap(jni) char **STRING_OUT "jobjectArray"
%typemap(jtype) char **STRING_OUT "String[]"
%typemap(jstype) char **STRING_OUT "String[]"
%typemap(javain) char **STRING_OUT "$javainput"

%typemap(in) char **STRING_OUT($*1_ltype temp) {
  if (!$input) {
    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null");
    return $null;
  }
  if (JCALL1(GetArrayLength, jenv, $input) == 0) {
    SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element");
    return $null;
  }
  $1 = &temp; 
  *$1 = 0;
}

%typemap(argout) char **STRING_OUT {
  jstring jnewstring = NULL;
  if ($1) {
     jnewstring = JCALL1(NewStringUTF, jenv, *$1);
  }
  JCALL3(SetObjectArrayElement, jenv, $input, 0, jnewstring); 
}

/* 
 * char *BYTE typemaps. 
 * These are input typemaps for mapping a Java byte[] array to a C char array.
 * Note that as a Java array is used and thus passeed by reference, the C routine 
 * can return data to Java via the parameter.
 *
 * Example usage wrapping:
 *   void foo(char *array);
 *  
 * Java usage:
 *   byte b[] = new byte[20];
 *   modulename.foo(b);
 */
%typemap(jni) char *BYTE "jbyteArray"
%typemap(jtype) char *BYTE "byte[]"
%typemap(jstype) char *BYTE "byte[]"
%typemap(in) char *BYTE {
  $1 = (char *) JCALL2(GetByteArrayElements, jenv, $input, 0); 
}

%typemap(argout) char *BYTE {
  JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *) $1, 0); 
}

%typemap(javain) char *BYTE "$javainput"

/* Prevent default freearg typemap from being used */
%typemap(freearg) char *BYTE ""


然后再当前目录cmd下运行命令:

swig.exe -c++ -java -package ctp.thostapi -outdir src -o thosttraderapi_wrap.cpp thostapi.i

当前目录下生成了:这两个文件是用于包装原来C++接口的文件

thosttraderapi_wrap.h
thosttraderapi_wrap.cpp

在这里插入图片描述
打开src文件夹,可以看到这时在里面生成了一系列方法的java文件,如下

CThostFtdcAccountregisterField.java
CThostFtdcAuthenticationInfoField.java
… … …
thosttradeapiJNI.java

在cmd中cd到src文件夹底下,运行命令

javac *.java

运行结束之后可以看到生成了等量的class文件,将所有的class文件拷贝到\ctp\thostapi\文件夹中,cmd下cd到6.3.15_20190220_tradeapi64_se_windows目录下,运行命令.即可在当前文件夹下得到了jar包thostapi.jar。

jar cf thostapi.jar ctp

. 通过C++得到java可调用的dll动态库
接下来在wrap文件夹中,建立一个C++工程,工程为Win32控制台应用程序,工程名为thostapi_wrap,点下一步,工程的应用程序类型选DLL,附加选项选空项目。另外建好项目后,在工程属性-c/c+±代码生成-运行库中选多线程(/MT)。步骤图如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
完成之后,将如下文件拷贝到\wrap\thostapi_wrap文件夹下
ThostFtdcMdApi.h
ThostFtdcTraderApi.h
ThostFtdcUserApiDataType.h
ThostFtdcUserApiStruct.h
thostmduserapi_se.lib
thosttraderapi_se.lib
thosttraderapi_wrap.cpp
thosttraderapi_wrap.h
libiconv.lib
iconv.h
其中
libiconv.lib 和iconv.h 在github下载的包里找
在thostapi_wrap.cpp 文件任意位置添加

#pragma comment(lib,"libiconv.lib")

在c++工程中添加现有项,将这些文件全部添加到工程中去。下面还要做几步:
将你安装jdk目录\Java\jdk1.8.0_111\include下的jni.h和win32文件夹下的jni_md.h, jawt_md.h一共三个文件拷贝到安装vs的include目录底下\Microsoft Visual Studio 12.0\VC\include。这是因为thosttraderapi_wrap.cpp文件中包含了<jni.h>,这是用于生成Java可调用接口的库文件。

这所有完成之后,C++工程中文件应该如下:

在这里插入图片描述
然后选择release版编译。我们按F7编译,在\wrap\thosttraderapi_wrap\Release目录底下可见thosttraderapi_wrap.dll动态库文件,说明编译成功,这样CTP Java API就编译成功了。编译中如果出现error LNK2005: abort 已经在 LIBCMT.lib(abort.obj) 中定义…等错误,可以右击工程 - 属性 ”配置属性 - 链接器 - 命令行” 添加: /NODEFAULTLIB:"libcmt.lib"解决。

在这里插入图片描述
在这里插入图片描述
修改jdk版本配置
在这里插入图片描述
完成就可在x64文件夹下看到如下:
在这里插入图片描述

下面就是需要将我们所需要的整合到一个包下.好方便项目引入.
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值