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 ""
  • 相关阅读:
    fedora29 安装mongodb 4.0,6问题记录
    乱花渐入迷人眼------从解决jqueryEasyUI上传插件提交ajax请求谈网页调试
    thinkphp5权限仿制
    基于tornado python pandas和bootstrap上传组件的mongodb数据添加工具
    tornado下pandas ndarray乱试
    一个tornado框架下的文件上传案例
    一例tornado框架下利用python panda对数据进行crud操作
    PHP 基础语法实例及注意事项
    转:github使用教程(重装系统后遇到问题该文章帮我解决了)
    ubuntu同步系统时间命令
  • 原文地址:https://www.cnblogs.com/anyun/p/9268895.html
Copyright © 2011-2022 走看看