目的
在 golang 项目中使用 C++实现的CTP接口
学习推荐 blog
https://www.cnblogs.com/terencezhou/p/10059156.html
准备工作
CTP接口文件:4个.h头文件+ 2个.so动态连接库
SWIG 简介
SWIG是一个软件开发工具,用于将C或C++程序与其他高级程序语言连接起来。它支持多种目标语言,包括脚本语言如Javascript、Perl、PHP、Python、Tcl、Ruby,也包括非脚本语言如C#,Common Lisp (CLISP, Allegro CL, CFFI, UFFI)、D、Go 、Java等。SWIG解析C或C++接口,生成“连接代码”,使其他高级语言可以调用C或C++的代码。
官方文档 https://www.swig.org/Doc3.0/SWIG.html
步骤
1. 编写接口文件 ctpgo.i
%module(directors="1") lib
%header %{
#include "ThostFtdcUserApiDataType.h"
#include "ThostFtdcUserApiStruct.h"
#include "ThostFtdcMdApi.h"
#include "ThostFtdcTraderApi.h"
%}
#include "std_string.i"
%feature("director") CThostFtdcMdSpi;
%feature("director") CThostFtdcTraderSpi;
%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"
%include "ThostFtdcTraderApi.h"
代码说明:
1. 第一行以%module指令开头,声明模块lib
2. 定义需要在_wrapper.cpp文件里包含的头文件,即%{ %}之间的部分。本文件引用四个CTP接口头文件
2. 生成ctpgo_wrap.cxx、ctpgo_wrap.h、lib.go文件
swig -c++ -go -intgosize 64 ctpgo.i
.h和.cxx文件是用于包装原来C++接口的文件
3. 编写libctpgo.go
package lib
/*
#cgo linux LDFLAGS: -fPIC -L${SRCDIR} -Wl,-rpath,${SRCDIR} -lctpgo -lthostmduserapi_se -lthosttraderapi_se -lstdc++
#cgo linux CPPFLAGS: -fPIC -I${SRCDIR}
*/
import "C"
注意,注释不能删除,import上面的注释时C代码,且import上面不能有空行。
4. 编写CMakeLists.txt
cmake_minimum_required (VERSION 3.20)
project (ctpgo C CXX)
set(MY_LIB_PATH ${CMAKE_CURRENT_SOURCE_DIR})
set(DIR_LIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/ctpgo_wrap.cxx)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_library(ctpgo SHARED ${DIR_LIB_SRCS})
TARGET_LINK_LIBRARIES(ctpgo ${MY_LIB_PATH}/libthosttraderapi_se.so ${MY_LIB_PATH}/libthostmduserapi_se.so)
代码说明:
1. cmake版本 3.20及以上
2. 设置路径
3. C11编译
4. 链接两个so文件
5. 生成Makefile文件
cmake .
6. 生成libctpgo.so文件
make
7. 编译为包 lib 测试转换是否成功,或者也可以自己写个文件测试
go build .
遇到的问题及解决方案
1. undefined reference to ‘xxx’
原因:未添加动态链接库(.so)的连接参数
结论:在libctpgo.go中加入cgo指令
2. libthosttraderapi_se.so: file not recognized: File truncated
原因:编译数据被截断或则编译过程中发生异常退出系统导致数据丢失。
结论:属于操作错误,与文件无关,多试几次就行了
3. could not determine kind of name for C.xxx
原因:/**/中间是C代码,之后接 import "C" 如果存在空行 就会报错.could not determine kind of name for C.*
结论:import “C” 之前不能有空行