c++ 动态链接库测试时,若使用 c++ 语言 编写测试程序,成本较高,是否能快速生成 python 调用接口呢,本文旨在介绍 swig 工具的使用,让你掌握接口的 c++api 接口的封装,便于上层测试。其他方法还有 cffi、boost python 等;
此外也可以利用 python 完成 c++ 函数的单元测试
%module(directors="1") datasolution
%{
#include "ServerApi.h"
#include "BusPackage.h"
#include "OpenBusApiStru.h"
%}
%feature("director") CServerApiSpi;
%include "BusStruct.h"
%include "OpenBusApiStru.h"
%include "ServerApi.h"
%include "BusPackage.h"
swig -threads -c++ -python "D:\Program Files\datasolution\data.i"
datasolution.py
data_wrap.h
data_wrap.cxx
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 3.0.10
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.
from sys import version_info as _swig_python_version_info
if _swig_python_version_info >= (2, 7, 0):
def swig_import_helper():
import importlib
pkg = __name__.rpartition('.')[0]
mname = '.'.join((pkg, '_datasolution')).lstrip('.')
try:
return importlib.import_module(mname)
except ImportError:
return importlib.import_module('_datasolution')
_datasolution = swig_import_helper()
del swig_import_helper
elif _swig_python_version_info >= (2, 6, 0):
def swig_import_helper():
from os.path import dirname
import imp
fp = None
try:
fp, pathname, description = imp.find_module('_datasolution', [dirname(__file__)])
except ImportError:
import _datasolution
return _datasolution
if fp is not None:
try:
_mod = imp.load_module('_datasolution', fp, pathname, description)
finally:
fp.close()
return _mod
_datasolution = swig_import_helper()
重命名为_datasolution.pyd
新建一个空的 dll 项目
导入头文件与 cxx 文件
项目引入 python\include 目录及链接器导入 lib
在c++工程中添加现有项,将这些文件全部添加到工程中去。下面还要做几步:
将你安装的python下include文件夹的路径添加至C++附加包含目录。我的路径是C:\Python27\include;,C++附加包含目录在工程-属性-配置属性-c/c++处。
将你安装的python中python27.lib添加至工程附加依赖项中。我的lib路径是C:\Python27\libs\python27.lib;,附加依赖项在工程-属性-配置属性-链接器-输入处。
这样全部完成之后,选择Release版本,我们按F7编译,在\__datasolution\Release目录底下可见__datasolution.dll动态库文件,说明编译成功,将其重命名为__datasolution.pyd,这样__datasolution Python API就编译成功了。
#coding:utf-8
import datasolution as dsapi
class CApiSpi(dsapi.CServerApiSpi):
def OnRcvReq(self, nReqID, pCondition, nLength, nSeqNO):
print nReqID
print pCondition
print nLength
print nSeqNO
csapi=dsapi.CServerApi()
errormsg=dsapi.ERROR_INFO()
csapi.Init(errormsg)
errormsg=dsapi.ERROR_INFO()
csapi.Connect("172.28.10.25", 2008, errormsg)
print errormsg.nErrID
print errormsg.strErrMsg
errormsg=dsapi.ERROR_INFO()
csapi.AddService(2689, errormsg)
print errormsg.nErrID
print errormsg.strErrMsg
errormsg=dsapi.ERROR_INFO()
loginReq=dsapi.CFFEX_IN_OUT_MONEY()
loginReq.ACCOUNTID='801000849'
loginReq.AMOUNT=0.05
loginReq.BROKERID='0125'
loginReq.CURRENCY='USD'
loginReq.SECONDSERIALNO='00000012222'
#loginReq['nEventHandle'] = 100000001
'''
{"BrokerID", STRING_TYPE_S},
{"AccountID", STRING_TYPE_S},
{"Currency", STRING_TYPE_S},
{"Amount", DOUBLE_TYPE_S},
{"AmountDirection", CHAR_TYPE_S},
{"SerialNo", STRING_TYPE_S},
{"Date", STRING_TYPE_S},
{"Time", STRING_TYPE_S}
'''
# reqid = reqid + 1 # 请求数必须保持唯一性
print csapi.Request(5002,loginReq,1000, errormsg)
cpack=csapi.CreatePackage()