一、CTPFutrueProvider

https://github.com/fouvy/CTPFutrueProvider

动态链接库:CTPWrapper 项目概述

应用程序向导已为您创建了此 CTPWrapper DLL。

本文件概要介绍组成 CTPWrapper 应用程序的每个文件的内容。

CTPWrapper.vcproj

这是使用应用程序向导生成的 VC++ 项目的主项目文件。

它包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。

CTPWrapper.cpp

这是主 DLL 源文件。

其他标准文件:

StdAfx.h, StdAfx.cpp

这些文件用于生成名为 CTPWrapper.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。

其他注释:

应用程序向导使用“TODO:”指示应添加或自定义的源代码部分。

二、PInvoke的方式

今天主要讲以下的方式:

http://www.360doc.com/content/14/0211/00/3218170_351502832.shtml
从C#的托管代码中,调用C++的非托管代码,主要是使用PInvoke的方式,但CTP的API接口中存在以下两个特点,使我们无法直接调用
1、各种请求(Req函数)是Api类的成员函数,而不是静态函数
2、各种响应,是需要继承Spi类之后,才能在重写的虚函数(是叫这名字吧。。。)中得到回传数据

针对这两个特点,我使用的方法是
1、新建WIN32项目(项目名:CTPWrapper),将Api类的成员函数扩展成静态函数,如:

Code:
///创建TraderApi
///@param pszFlowPath 存贮订阅信息文件的目录,默认为当前目录
///@return 创建出的UserApi
extern "C" CTPWRAPPER_API void* CreateTraderApi(const char *pszFlowPath)
{return CThostFtdcTraderApi::CreateFtdcTraderApi(pszFlowPath);
};///注册前置机网络地址
///@param pszFrontAddress:前置机网络地址。
///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:17001”。
///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。
extern "C" CTPWRAPPER_API void TraderRegisterFront(void *instance,char *pszFrontAddress)
{((CThostFtdcTraderApi *)instance)->RegisterFront(pszFrontAddress);
};

其中的CTPWRAPPER_API 是
Code:

#define CTPWRAPPER_API __declspec(dllexport)

就像这样,实现了两个标准的WIN32API,将其编译成DLL,从C#中就可以直接调用了。

C#中定义PInvoke方法如下
Code:

[DllImport("CTPWrapper.dll")]internal static extern IntPtr CreateTraderApi(string pszFlowPath);[DllImport("CTPWrapper.dll")]internal static extern void TraderRegisterFront(IntPtr hTrader, String address);

在C#中创建并使用TraderApi
Code:

IntPtr _instance = CreateTraderApi("");
TraderRegisterSpi(_instance, this._listener.Instance);

2、使用函数指针从C++的函数中调用C#的方法
为保证C++的函数能够正确的调用C#的方法,函数指针的构成必须一致,因此分别在C++和C#中定义以下内容:
Code:
C++

///登录请求响应
typedef void (WINAPI *OnRspUserLoginCallback)(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;

C#
Code:

public delegate void UserLoginCallback(IntPtr pRspUserLogin, IntPtr pRspInfo, int nRequestID, [MarshalAs(UnmanagedType.U1)]bool bIsLast);

(这里注意下bool类型的定义,在这里我被郁闷了好久:()

然后在创建Spi类的时候将C#的回调函数指针作为参数传到C++中
Code:
C++中Spi的构造函数

CTPTraderSpi::CTPTraderSpi(OnRspUserLoginCallback callback)
{this->m_OnRspUserLoginCallback = callback;
}

同1的方法,将构造函数扩展为WIN32API
Code:

extern "C" CTPWRAPPER_API void* WINAPI CreateTraderSpiClass(OnRspUserLoginCallback callback)
{CTPTraderSpi *spi = new CTPTraderSpi(callback);return (void*)spi;
}

这样,在C++中得到响应时,就可以调用C#的方法了
Code:
///登录请求响应

void CTPTraderSpi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{if(this->m_OnRspUserLoginCallback){(this->m_OnRspUserLoginCallback)(pRspUserLogin ,pRspInfo,nRequestID,bIsLast);}
}

在C#中,这样使用
Code:

UserLoginCallback userLoginCallback = new UserLoginCallback(this.OnUserLogin);_instance = CreateTraderSpiClass(userLoginCallback);

OK,到这里,最最核心的东西已经说完了,剩下的都是些技巧和体力活了
比如Spi的回调函数有很多,总不可能在C#中创建好了再一个个传到C++里,怎办呢?其实我是用了个Struct,包好了一起传的
Code:

 /// <summary>/// 回调函数指针结构/// </summary>[StructLayout(LayoutKind.Sequential)]internal struct CTPTraderSpiCallbackStruct{///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。internal FrontConnectedCallback FrontConnectedCallback;///当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。///@param nReason 错误原因///        0x1001 网络读失败///        0x1002 网络写失败///        0x2001 接收心跳超时///        0x2002 发送心跳失败///        0x2003 收到错误报文internal FrontDisconnectedCallback FrontDisconnectedCallback;///心跳超时警告。当长时间未收到报文时,该方法被调用。///@param nTimeLapse 距离上次接收报文的时间internal HeartBeatWarningCallback HeartBeatWarningCallback;///登录请求响应internal UserLoginCallback UserLoginCallback;///登出请求响应internal UserLogoutCallback UserLogoutCallback;}

以下略
剩下还有一些细节问题,回头再慢慢说好了,整个过程被我封装成了两个工程
C++:CTPWrapper
C#:CTPInterop
由于还有很多工作没有完成,也就不发布出来了,有兴趣的朋友可以通过邮件和我联系,我把工程代码发给你
mail:lumen.xh@gmail.com

当然,如果有朋友愿意和我一起把剩下的部分建立起来的话,那就更好了:D

(转)C#封装CTP相关推荐

  1. 上海期货交易所CTP行情和交易接入

    发布时间:2018-09-25 技术:C++11,动态库的制作 概述 CTP的接入Demo 详细 代码下载:http://www.demodashi.com/demo/14125.html 本文档不介 ...

  2. CTP程序化交易入门系列之六:报单(一)

    行情(mduserapi)这一块终于介绍的差不多了,下面着重介绍交易(traderapi)相关.再次强调两点: 一.交易和行情是完全独立的,互不干扰: 二.本系列用Python版本讲解,主要考虑到Py ...

  3. vn.py源码解读(五、主引擎代码分析----CTP模块)

    上一篇文章讲了MainEngine中的初始化函数,重点是DataEngine的讲解.有了对行情数据的处理,还需要有行情数据的来源.在MainEngine的初始化函数后面的一个函数就是addGatewa ...

  4. java ctp行情_javaCtp: java版本期货程序化交易系统,包括行情服务,交易服务会逐步完善...

    java_vnpy 介绍 java版本期货程序化交易系统,包括行情服务,交易服务会逐步完善,CTP版本上期技术官网下载6.3.15 穿透式, 目前项目无架构设计,只针对ctp进行封装调用,实现基本交易 ...

  5. 量化交易数据接口如何获取实时行情数据的呢?

    基本都是自己封装CTP接口,程序端实现多账户.多策略的行情信号接收和委托提交/回报处理.也可以用 QuantBox/QuantBox_XAPI · GitHub 这样的封装的比较好.多接口统一API的 ...

  6. 通达信期货ctp交易接口进行封装对接?

    CTP接口除官方发布的C++动态库外,很多人也提供了Python.Java.C#等各主流语言的接口,可搜索相应的开发方法.一个连接能够查询的股票数量是有限的,性能也不高,但是可以创建多个api实例并发 ...

  7. ctp java_上期CTP 封装JAVA API window Swig

    1 首先在http://www.sfit.com.cn/5_2_DocumentDown.htm 下载CTP  后得到下面这些文件 2 我们选用32位版本20160606_tradeapi_windo ...

  8. 上期技术CTPAPI封装COM组件ctp开放平台openctp环境7_24小时x64组件python_delphi调用演示程序

    源码下载地址:https://gitee.com/topview999/TopViewQHTCtpCom 新修改后的python调用COM组件,pyside2制作的UI界面.体验一下远超VeighNa ...

  9. java ctp行情_java-ctp

    java-ctp java包装的上期ctp,用swig技术实现. 2014-4-7 10:09:11 项目已经搭建好,上传到这里方法还不会.时间比较紧,有空上传上来. 2014-7-31 22:43: ...

  10. 封装时间转换工具类_利用swig封装C++的dll为C#方便使用

    使用C++开发界面,时间效率上来说,不如C#开发的快和方便.但是CTP的库是C++的,并没有C#的库,网上也有人用C#的PINVOKE的方式将C++的函数一个个转换为C#能用的接口,我是看了下,原理o ...

最新文章

  1. 不同版本的Chrom浏览器对应的ChromDriver的版本
  2. Seafile - 最好的 Dropbox 开源替代,面向团队而设计
  3. expressjs路由和Nodejs服务器端发送REST请求 - - ITeye博客
  4. 上周五,小编参加了一场高大上的“9”会
  5. pandas to_sql保存数据到数据库后,添加自增长的主键ID(PRIMARY KEY)
  6. 双向循环链表涉及双向指针的基本操作(C语言)
  7. 国内外公有云对比:功能介绍、性能测试
  8. 商业智能应用的五大步骤
  9. 如何连接局域网_Minecraft我的世界局域网联机问题(windows平台)
  10. Mathematica/偏导数/最小二乘法(线性回归)
  11. vistor和tsmserver不在同一台机器上的连接问题
  12. 【BZOJ4372】烁烁的游戏(点分树)
  13. 匿名认证(Anonymous Authentication)
  14. 一文带你了解学习python的用处及好处,建议收藏
  15. html ---烟花
  16. Linux 解压缩文件到指定目录
  17. 音视频QoE核心指标
  18. 985毕业,半路出家28岁进军Java,坚持奋斗了三年现如今年薪36W+
  19. 百度云盘云知梦php_[云知梦]WEB前端开发_WEB前端新手入门视频教程[百度云盘]
  20. es教程——地图搜索

热门文章

  1. httpd-2.4实现虚拟主机、访问控制及https功能
  2. JavaScript 学习笔记4
  3. Ios开发之Category
  4. linux c 笔记 线程控制(一)
  5. Modbus通讯协议学习 - 认识篇
  6. oracle-第N篇加强专题
  7. [算法]圆圈中最后剩下的数
  8. 结对编程之设计电梯控制程序
  9. 洛谷2863 [Usaco06JAN]牛的舞会
  10. FZU 2041 二分枚举