zoukankan      html  css  js  c++  java
  • CTP API 开发之二 :制作CTP java版 API

    目前上期技术CTP系统提供的API版本是C++版本

    SWIG是一个能将C/C++接口转换为其他语言的工具,目前可以支持Python,Java,R等语言。
    本文主要介绍Windows 32/64位平台下利用Swig工具将CTP C++接口API转换为Java可调用的接口。

    1、从CTP官网下载最新API包,包中包含32位和64位。API文件包清单:

    2、下载安装Swig软件:

    3、在API文件包中创建thostapi.i 和various.i文件,thostapi.i是一个接口文件,用于告诉swig为哪些类和方法创建接口

    various.i是用于将C++接口中的数组参数转换为java 的Array的工具类

    %module(directors="1") thosttraderapi 
    %include "various.i"
    %apply char **STRING_ARRAY { char *ppInstrumentID[] }
    %{ 
    #include "ThostFtdcMdApi.h"
    #include "ThostFtdcTraderApi.h"
    %} 
    %feature("director") CThostFtdcMdSpi; 
    %include "ThostFtdcUserApiDataType.h"
    %include "ThostFtdcUserApiStruct.h" 
    %include "ThostFtdcMdApi.h"
    %feature("director") CThostFtdcTraderSpi;
    %include "ThostFtdcTraderApi.h"

    4、生成java接口:

    在当前文件夹创建src/ctp文件夹用于放置生成的java文件

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

    运行完成之后,可在当前文件夹中看到用于包装原来C++接口的文件:

     

    5、通过C++得到java可调用的动态库

    创建一个C++工程,应用程序类型选择DLL,将以下文件添加到工程中去:

    将dk目录Javajdk1.8.0_111include下的jni.hwin32文件夹下的jni_md.h, jawt_md.h一共三个文件

    拷贝到安装vs的include目录底下Microsoft Visual Studio 12.0VCinclude

    因为thosttraderapi_wrap.cpp文件中包含了<jni.h>,是用于生成Java可调用接口的库文件。

     将如下8个函数注释掉,这几个函数中涉及到将字符串转换为char类型,有问题:

    Java_ctp_thosttraderapi_thosttradeapiJNI_THOST_1FTDC_1VTC_1BankBankToFuture_1get 
    Java_ctp_thosttraderapi_thosttradeapiJNI_THOST_1FTDC_1VTC_1BankFutureToBank_1get 
    Java_ctp_thosttraderapi_thosttradeapiJNI_THOST_1FTDC_1VTC_1FutureBankToFuture_1get 
    Java_ctp_thosttraderapi_thosttradeapiJNI_THOST_1FTDC_1VTC_1FutureFutureToBank_1get 
    Java_ctp_thosttraderapi_thosttradeapiJNI_THOST_1FTDC_1FTC_1BankLaunchBankToBroker_1get 
    Java_ctp_thosttraderapi_thosttradeapiJNI_THOST_1FTDC_1FTC_1BrokerLaunchBankToBroker_1get 
    Java_ctp_thosttraderapi_thosttradeapiJNI_THOST_1FTDC_1FTC_1BankLaunchBrokerToBank_1get 
    Java_ctp_thosttraderapi_thosttradeapiJNI_THOST_1FTDC_1FTC_1BrokerLaunchBrokerToBank_1get

    之后进行编译,生成java可调用的动态库文件thosttraderapi_wrap.dll:

    6、创建java项目,将三个动态库和之前生成的src/ctp包拷贝到项目,并加载动态库进来:

    到此java API制作完成,可以进行java开发了

     附various.i:

    /* 
     * 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;
        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;
    }
    
    %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 {
        int i;
        int len=0;
        jstring temp_string;
        const jclass clazz = JCALL1(FindClass, jenv, "java/lang/String");
    
        while ($1[len]) len++;    
        jresult = JCALL3(NewObjectArray, jenv, len, clazz, NULL);
        /* exception checking omitted */
    
        for (i=0; i<len; i++) {
          temp_string = JCALL1(NewStringUTF, jenv, *result++);
          JCALL3(SetObjectArrayElement, jenv, jresult, 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; 
    }
    
    %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 ""
  • 相关阅读:
    Compression algorithm (deflate)
    tcpip数据包编码解析(chunk and gzip)_space of Jialy_百度空间
    What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
    gzip压缩算法: gzip 所使用压缩算法的基本原理
    Decompressing a GZip Stream with Zlib
    Frequently Asked Questions about zlib
    how to decompress gzip stream with zlib
    自己动手写web服务器四(web服务器是如何通过压缩数据,web服务器的gzip模块的实现)
    What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
    C语言抓http gzip包并解压 失败 C/C++ ChinaUnix.net
  • 原文地址:https://www.cnblogs.com/anyun/p/9268895.html
Copyright © 2011-2022 走看看