• 【转】CTP Python API及Demo(利用Swig 封装)Windows版(mduserapi)


    原文链接:https://blog.csdn.net/pjjing/article/details/77338482

    1. 环境准备:

      1) VS 2015

      2) Python 3.7 64位

           3)   CTP API (从 http://www.sfit.com.cn/5_2_DocumentDown.htm 下载,此文档使用的是  http://www.sfit.com.cn/APIHistory1.html  下载的 6.3.11_20180109 版本)

        

    error.dtd
    error.xml
    ThostFtdcMdApi.h
    ThostFtdcTraderApi.h
    ThostFtdcUserApiDataType.h
    ThostFtdcUserApiStruct.h
    thostmduserapi.dll
    thostmduserapi.lib
    thosttraderapi.dll
    thosttraderapi.lib
    

      

           4)   Swing

                  下载地址: https://sourceforge.net/projects/swig/files/。本文用的是 3.0.12 版本

        使用方式:下载完成后,解压缩,然后 将存放的文件路径 加到 系统变量 PATH 中。

            

           5)   liviconv 库

        这个库主要适用于字节编码转换,因为CTP的中文是GB2312编码,转换为UTF-8编码,适合python输出

        编译方法:按照  https://blog.csdn.net/ghevinn/article/details/9825765 步骤

        备注:1. 本次使用的是最新的 1.16 版本,可以通过 http://ftp.gnu.org/pub/gnu/libiconv/, 查询当前可用的版本

              2. VS  编译生成的是 Release x64 位。     

    2. 通过Swig得到python接口文件

    在刚刚下载得到的API文件夹20180109_tradeapi64_windows内,新建文件 thostmduserapi.i,内容如下

    %module(directors="1") thostmduserapi
    %{
    #include "ThostFtdcMdApi.h"
    #include "iconv.h"
    %}
    
    %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;
    
    %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] = {};
                const char **in = (const char **)&$1;
                char *out = buf;
                size_t inlen = strlen($1), outlen = 4096;
    
                if (iconv(cd, in, &inlen, &out, &outlen) != static_cast<size_t>(-1))
    			{
    				size_t size = outlen;
    				while (size && (buf[size - 1] == '')) --size;
    				resultobj = SWIG_FromCharPtrAndSize(buf, size);
    			}
                iconv_close(cd);
            }
        }
    }
    
    %typemap(in) char *[] {
      /* Check if is a list */
      if (PyList_Check($input)) {
        int size = PyList_Size($input);
        int i = 0;
        $1 = (char **) malloc((size+1)*sizeof(char *));
        for (i = 0; i < size; i++) {
          PyObject *o = PyList_GetItem($input, i);
          if (PyString_Check(o)) {
            $1[i] = PyString_AsString(PyList_GetItem($input, i));
          } else {
            free($1);
            PyErr_SetString(PyExc_TypeError, "list must contain strings");
            SWIG_fail;
          }
        }
        $1[i] = 0;
      } else {
        PyErr_SetString(PyExc_TypeError, "not a list");
        SWIG_fail;
      }
    }
    
    // This cleans up the char ** array we malloc'd before the function call
    %typemap(freearg) char ** {
      free((char *) $1);
    }
    %include "ThostFtdcUserApiDataType.h"
    %include "ThostFtdcUserApiStruct.h"
    %include "ThostFtdcMdApi.h"

    这是一个接口文件,用于告诉swig为哪些类和方法创建接口。打开windows cmd工具,cd到当前目录20180109_tradeapi_windows下。 在cmd中运行命令

    swig -threads -c++ -python thostmduserapi.i

    等到运行完成后,可以看到当前目录下生成了

    thostmduserapi_wrap.h
    thostmduserapi_wrap.cxx
    thostmduserapi.py
    

      

    .h和.cx文件是用于包装原来C++接口的文件,下面要用。.py文件是python调用方法的接口文件。

    3. 通过C++得到python可调用的pyd动态库

    在当前文件夹下建立一个C++工程,工程的应用程序类型选DLL,工程名为_thostmduserapi.i(建工程的步骤也可参考https://blog.csdn.net/pjjing/article/details/53186394这篇文章第3步开头),

    需要注意几点:1)工程建64位dll类型,2)运行库选多线程(/MT)。然后将如下文件拷贝到_thostmduserapi文件夹下:

    ThostFtdcMdApi.h
    ThostFtdcUserApiDataType.h
    ThostFtdcUserApiStruct.h
    thostmduserapi.lib
    thostmduserapi_wrap.h
    thostmduserapi_wrap.cxx
    libiconv.lib
    iconv.h
    

      

    在c++工程中添加现有项,将这些文件全部添加到工程中去。下面还要做几步:

       1)将你安装的python下include文件夹的路径添加至C++附加包含目录。我的路径是 D:Program Files (x86)Python37include;,C++附加包含目录在工程-属性-配置属性-c/c++。

            

     2)将你安装的python中python37.lib添加至工程附加依赖项中。我的lib路径是 D:Program Files (x86)Python37libspython37.lib;,附加依赖项在 工程-属性-配置属性-链接器-输入。  

           

       3)这样全部完成之后,选择Release版本 64位,我们按F7编译,在\_thostmduserapiRelease目录底下可见_thostmduserapi.dll动态库文件,说明编译成功,将其重命名为_thostmduserapi.pyd,这样CTP Python API就编译成功了。

            【有可能需要将 iconv.h 和 libIconv.lib 将放在待生成的 Release 目录下】


    如果编译出现一些问题,可以百度解决。可能涉及到要修改pyconfig.h,object.h,Python.h三个文件。

    问题1: 找不到 无法将参数 2 从“char **”转换为“const char **”, 原文的 thostmduserapi.i 在 VS2015 编译时,有问题,需要将 char **in = &$1;  改为   const char **in = (const char **)&$1;

    问题2:无法解析的外部符号 __imp_setlocale,解决办法:在 thostmduserapi_wrap.cxx 的头部加上  #pragma comment(lib,"msvcrtd.lib")

    问题3:默认库“library”与其他库的使用冲突;使用 /NODEFAULTLIB:library,解决办法:(https://blog.csdn.net/larry_zeng1/article/details/86679869

                                            1.右击工程 - 属性 ”配置属性 - 链接器 - 输入 - 忽略特定库“,添加 ”libcmtd.lib“;

                                          或 2.右击工程 - 属性 ”配置属性 - 链接器 - 命令行” 添加:  /NODEFAULTLIB:"libcmtd.lib"

    4. Python Demo

    通过在c++中引入字符转码为utf-8,现在中文已经可以直接输出了,详见demo。
    新建文件md_demo_demo.py,注意文件同目录底下要有如下三个文件:

    thostmduserapi.py
    thostmduserapi.dll
    _thostmduserapi.pyd
    

      

  • 相关阅读:
    [JavaScript] cookie和storage
    react-interview-02
    简单实现一个Vue
    js获取当前页面url
    鸽巢原理
    20210412-1 原型设计作业
    案例分析作业
    软件工程的202103226-1编程作业
    阅读反馈
    软件工程第一课
  • 原文地址:https://www.cnblogs.com/bruce-he/p/11050714.html
Copyright © 2020-2023  润新知