305 lines
11 KiB
Python
305 lines
11 KiB
Python
|
# encoding: UTF-8
|
|||
|
|
|||
|
__author__ = 'CHENXY'
|
|||
|
|
|||
|
from ctp_struct import structDict
|
|||
|
|
|||
|
|
|||
|
|
|||
|
def processCallBack(line):
|
|||
|
orignalLine = line
|
|||
|
line = line.replace('\tvirtual void ', '') # 删除行首的无效内容
|
|||
|
line = line.replace('{};\n', '') # 删除行尾的无效内容
|
|||
|
|
|||
|
content = line.split('(')
|
|||
|
cbName = content[0] # 回调函数名称
|
|||
|
|
|||
|
cbArgs = content[1] # 回调函数参数
|
|||
|
if cbArgs[-1] == ' ':
|
|||
|
cbArgs = cbArgs.replace(') ', '')
|
|||
|
else:
|
|||
|
cbArgs = cbArgs.replace(')', '')
|
|||
|
|
|||
|
cbArgsList = cbArgs.split(', ') # 将每个参数转化为列表
|
|||
|
|
|||
|
cbArgsTypeList = []
|
|||
|
cbArgsValueList = []
|
|||
|
|
|||
|
for arg in cbArgsList: # 开始处理参数
|
|||
|
content = arg.split(' ')
|
|||
|
if len(content) > 1:
|
|||
|
cbArgsTypeList.append(content[0]) # 参数类型列表
|
|||
|
cbArgsValueList.append(content[1]) # 参数数据列表
|
|||
|
|
|||
|
createTask(cbName, cbArgsTypeList, cbArgsValueList, orignalLine)
|
|||
|
createProcess(cbName, cbArgsTypeList, cbArgsValueList)
|
|||
|
|
|||
|
# 生成.h文件中的process部分
|
|||
|
process_line = 'void process' + cbName[2:] + '(Task task);\n'
|
|||
|
fheaderprocess.write(process_line)
|
|||
|
fheaderprocess.write('\n')
|
|||
|
|
|||
|
# 生成.h文件中的on部分
|
|||
|
if 'OnRspError' in cbName:
|
|||
|
on_line = 'virtual void on' + cbName[2:] + '(dict error, int id, bool last) {};\n'
|
|||
|
elif 'OnRsp' in cbName:
|
|||
|
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error, int id, bool last) {};\n'
|
|||
|
elif 'OnRtn' in cbName:
|
|||
|
on_line = 'virtual void on' + cbName[2:] + '(dict data) {};\n'
|
|||
|
elif 'OnErrRtn' in cbName:
|
|||
|
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error) {};\n'
|
|||
|
else:
|
|||
|
on_line = ''
|
|||
|
fheaderon.write(on_line)
|
|||
|
fheaderon.write('\n')
|
|||
|
|
|||
|
# 生成封装部分
|
|||
|
createWrap(cbName)
|
|||
|
|
|||
|
|
|||
|
#----------------------------------------------------------------------
|
|||
|
def createWrap(cbName):
|
|||
|
"""在Python封装段代码中进行处理"""
|
|||
|
# 生成.h文件中的on部分
|
|||
|
if 'OnRspError' in cbName:
|
|||
|
on_line = 'virtual void on' + cbName[2:] + '(dict error, int id, bool last)\n'
|
|||
|
override_line = '("on' + cbName[2:] + '")(error, id, last);\n'
|
|||
|
elif 'OnRsp' in cbName:
|
|||
|
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error, int id, bool last)\n'
|
|||
|
override_line = '("on' + cbName[2:] + '")(data, error, id, last);\n'
|
|||
|
elif 'OnRtn' in cbName:
|
|||
|
on_line = 'virtual void on' + cbName[2:] + '(dict data)\n'
|
|||
|
override_line = '("on' + cbName[2:] + '")(data);\n'
|
|||
|
elif 'OnErrRtn' in cbName:
|
|||
|
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error)\n'
|
|||
|
override_line = '("on' + cbName[2:] + '")(data, error);\n'
|
|||
|
else:
|
|||
|
on_line = ''
|
|||
|
|
|||
|
if on_line is not '':
|
|||
|
fwrap.write(on_line)
|
|||
|
fwrap.write('{\n')
|
|||
|
fwrap.write('\ttry\n')
|
|||
|
fwrap.write('\t{\n')
|
|||
|
fwrap.write('\t\tthis->get_override'+override_line)
|
|||
|
fwrap.write('\t}\n')
|
|||
|
fwrap.write('\tcatch (error_already_set const &)\n')
|
|||
|
fwrap.write('\t{\n')
|
|||
|
fwrap.write('\t\tPyErr_Print();\n')
|
|||
|
fwrap.write('\t}\n')
|
|||
|
fwrap.write('};\n')
|
|||
|
fwrap.write('\n')
|
|||
|
|
|||
|
|
|||
|
|
|||
|
def createTask(cbName, cbArgsTypeList, cbArgsValueList, orignalLine):
|
|||
|
# 从回调函数生成任务对象,并放入队列
|
|||
|
funcline = orignalLine.replace('\tvirtual void ', 'void ' + apiName + '::')
|
|||
|
funcline = funcline.replace('{};', '')
|
|||
|
|
|||
|
ftask.write(funcline)
|
|||
|
ftask.write('{\n')
|
|||
|
ftask.write("\tTask task = Task();\n")
|
|||
|
|
|||
|
ftask.write("\ttask.task_name = " + cbName.upper() + ";\n")
|
|||
|
|
|||
|
# define常量
|
|||
|
global define_count
|
|||
|
fdefine.write("#define " + cbName.upper() + ' ' + str(define_count) + '\n')
|
|||
|
define_count = define_count + 1
|
|||
|
|
|||
|
# switch段代码
|
|||
|
fswitch.write("case " + cbName.upper() + ':\n')
|
|||
|
fswitch.write("{\n")
|
|||
|
fswitch.write("\tthis->" + cbName.replace('On', 'process') + '(task);\n')
|
|||
|
fswitch.write("\tbreak;\n")
|
|||
|
fswitch.write("}\n")
|
|||
|
fswitch.write("\n")
|
|||
|
|
|||
|
for i, type_ in enumerate(cbArgsTypeList):
|
|||
|
if type_ == 'int':
|
|||
|
ftask.write("\ttask.task_id = " + cbArgsValueList[i] + ";\n")
|
|||
|
elif type_ == 'bool':
|
|||
|
ftask.write("\ttask.task_last = " + cbArgsValueList[i] + ";\n")
|
|||
|
elif 'RspInfoField' in type_:
|
|||
|
ftask.write("\n")
|
|||
|
ftask.write("\tif (pRspInfo)\n")
|
|||
|
ftask.write("\t{\n")
|
|||
|
ftask.write("\t\ttask.task_error = " + cbArgsValueList[i] + ";\n")
|
|||
|
ftask.write("\t}\n")
|
|||
|
ftask.write("\telse\n")
|
|||
|
ftask.write("\t{\n")
|
|||
|
ftask.write("\t\tCThostFtdcRspInfoField empty_error = CThostFtdcRspInfoField();\n")
|
|||
|
ftask.write("\t\tmemset(&empty_error, 0, sizeof(empty_error));\n")
|
|||
|
ftask.write("\t\ttask.task_error = empty_error;\n")
|
|||
|
ftask.write("\t}\n")
|
|||
|
else:
|
|||
|
ftask.write("\n")
|
|||
|
ftask.write("\tif (" + cbArgsValueList[i][1:] + ")\n")
|
|||
|
ftask.write("\t{\n")
|
|||
|
ftask.write("\t\ttask.task_data = " + cbArgsValueList[i] + ";\n")
|
|||
|
ftask.write("\t}\n")
|
|||
|
ftask.write("\telse\n")
|
|||
|
ftask.write("\t{\n")
|
|||
|
ftask.write("\t\t" + type_ + " empty_data = " + type_ + "();\n")
|
|||
|
ftask.write("\t\tmemset(&empty_data, 0, sizeof(empty_data));\n")
|
|||
|
ftask.write("\t\ttask.task_data = empty_data;\n")
|
|||
|
ftask.write("\t}\n")
|
|||
|
|
|||
|
ftask.write("\tthis->task_queue.push(task);\n")
|
|||
|
ftask.write("};\n")
|
|||
|
ftask.write("\n")
|
|||
|
|
|||
|
|
|||
|
def createProcess(cbName, cbArgsTypeList, cbArgsValueList):
|
|||
|
# 从队列中提取任务,并转化为python字典
|
|||
|
fprocess.write("void " + apiName + '::' + cbName.replace('On', 'process') + '(Task task)' + "\n")
|
|||
|
fprocess.write("{\n")
|
|||
|
fprocess.write("\tPyLock lock;\n")
|
|||
|
|
|||
|
onArgsList = []
|
|||
|
|
|||
|
for i, type_ in enumerate(cbArgsTypeList):
|
|||
|
if 'RspInfoField' in type_:
|
|||
|
fprocess.write("\t"+ type_ + ' task_error = any_cast<' + type_ + '>(task.task_error);\n')
|
|||
|
fprocess.write("\t"+ "dict error;\n")
|
|||
|
|
|||
|
struct = structDict[type_]
|
|||
|
for key in struct.keys():
|
|||
|
print(key)
|
|||
|
if struct[key] == "string":
|
|||
|
fprocess.write("\t"+ 'error["' + key + '"] = boost::locale::conv::to_utf<char>(task_error.' + key + ', std::string("GB2312"));\n')
|
|||
|
else:
|
|||
|
fprocess.write("\t" + 'error["' + key + '"] = task_error.' + key + ';\n')
|
|||
|
|
|||
|
fprocess.write("\n")
|
|||
|
|
|||
|
onArgsList.append('error')
|
|||
|
|
|||
|
elif type_ in structDict:
|
|||
|
fprocess.write("\t"+ type_ + ' task_data = any_cast<' + type_ + '>(task.task_data);\n')
|
|||
|
fprocess.write("\t"+ "dict data;\n")
|
|||
|
|
|||
|
struct = structDict[type_]
|
|||
|
for key in struct.keys():
|
|||
|
print(key)
|
|||
|
if struct[key] == "string":
|
|||
|
fprocess.write("\t"+ 'data["' + key + '"] = boost::locale::conv::to_utf<char>(task_data.' + key + ', std::string("GB2312"));\n')
|
|||
|
else:
|
|||
|
fprocess.write("\t" + 'data["' + key + '"] = task_data.' + key + ';\n')
|
|||
|
|
|||
|
fprocess.write("\n")
|
|||
|
|
|||
|
onArgsList.append('data')
|
|||
|
|
|||
|
elif type_ == 'bool':
|
|||
|
onArgsList.append('task.task_last')
|
|||
|
|
|||
|
elif type_ == 'int':
|
|||
|
onArgsList.append('task.task_id')
|
|||
|
|
|||
|
onArgs = ', '.join(onArgsList)
|
|||
|
fprocess.write('\tthis->' + cbName.replace('On', 'on') + '(' + onArgs +');\n')
|
|||
|
|
|||
|
fprocess.write("};\n")
|
|||
|
fprocess.write("\n")
|
|||
|
|
|||
|
|
|||
|
def processFunction(line):
|
|||
|
line = line.replace('\tvirtual int ', '') # 删除行首的无效内容
|
|||
|
line = line.replace(') = 0;\n', '') # 删除行尾的无效内容
|
|||
|
|
|||
|
content = line.split('(')
|
|||
|
fcName = content[0] # 回调函数名称
|
|||
|
|
|||
|
fcArgs = content[1] # 回调函数参数
|
|||
|
fcArgs = fcArgs.replace(')', '')
|
|||
|
|
|||
|
fcArgsList = fcArgs.split(', ') # 将每个参数转化为列表
|
|||
|
|
|||
|
fcArgsTypeList = []
|
|||
|
fcArgsValueList = []
|
|||
|
|
|||
|
for arg in fcArgsList: # 开始处理参数
|
|||
|
content = arg.split(' ')
|
|||
|
if len(content) > 1:
|
|||
|
fcArgsTypeList.append(content[0]) # 参数类型列表
|
|||
|
fcArgsValueList.append(content[1]) # 参数数据列表
|
|||
|
|
|||
|
if len(fcArgsTypeList)>0 and fcArgsTypeList[0] in structDict:
|
|||
|
createFunction(fcName, fcArgsTypeList, fcArgsValueList)
|
|||
|
|
|||
|
# 生成.h文件中的主动函数部分
|
|||
|
if 'Req' in fcName:
|
|||
|
req_line = 'int req' + fcName[3:] + '(dict req, int nRequestID);\n'
|
|||
|
fheaderfunction.write(req_line)
|
|||
|
fheaderfunction.write('\n')
|
|||
|
|
|||
|
|
|||
|
def createFunction(fcName, fcArgsTypeList, fcArgsValueList):
|
|||
|
type_ = fcArgsTypeList[0]
|
|||
|
struct = structDict[type_]
|
|||
|
|
|||
|
ffunction.write('int TdApi::req' + fcName[3:] + '(dict req, int nRequestID)\n')
|
|||
|
ffunction.write('{\n')
|
|||
|
ffunction.write('\t' + type_ +' myreq = ' + type_ + '();\n')
|
|||
|
ffunction.write('\tmemset(&myreq, 0, sizeof(myreq));\n')
|
|||
|
|
|||
|
for key, value in struct.items():
|
|||
|
if value == 'string':
|
|||
|
line = '\tgetStr(req, "' + key + '", myreq.' + key + ');\n'
|
|||
|
elif value == 'char':
|
|||
|
line = '\tgetChar(req, "' + key + '", &myreq.' + key + ');\n'
|
|||
|
elif value == 'int':
|
|||
|
line = '\tgetInt(req, "' + key + '", &myreq.' + key + ');\n'
|
|||
|
elif value == 'float':
|
|||
|
line = '\tgetDouble(req, "' + key + '", &myreq.' + key + ');\n'
|
|||
|
ffunction.write(line)
|
|||
|
|
|||
|
if type_ == 'CThostFtdcInputOrderField':
|
|||
|
print(key, value)
|
|||
|
print(line)
|
|||
|
|
|||
|
ffunction.write('\tint i = this->api->' + fcName + '(&myreq, nRequestID);\n')
|
|||
|
ffunction.write('\treturn i;\n')
|
|||
|
|
|||
|
ffunction.write('};\n')
|
|||
|
ffunction.write('\n')
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#########################################################
|
|||
|
apiName = 'TdApi'
|
|||
|
|
|||
|
fcpp = open('ThostFtdcTraderApi.h', 'r')
|
|||
|
ftask = open('ctp_td_task.cpp', 'w')
|
|||
|
fprocess = open('ctp_td_process.cpp', 'w')
|
|||
|
ffunction = open('ctp_td_function.cpp', 'w')
|
|||
|
fdefine = open('ctp_td_define.cpp', 'w')
|
|||
|
fswitch = open('ctp_td_switch.cpp', 'w')
|
|||
|
fheaderprocess = open('ctp_td_header_process.h', 'w')
|
|||
|
fheaderon = open('ctp_td_header_on.h', 'w')
|
|||
|
fheaderfunction = open('ctp_td_header_function.h', 'w')
|
|||
|
fwrap = open('ctp_td_wrap.cpp', 'w')
|
|||
|
|
|||
|
define_count = 1
|
|||
|
|
|||
|
for line in fcpp:
|
|||
|
if "\tvirtual void On" in line:
|
|||
|
processCallBack(line)
|
|||
|
elif "\tvirtual int" in line:
|
|||
|
processFunction(line)
|
|||
|
|
|||
|
fcpp.close()
|
|||
|
ftask.close()
|
|||
|
fprocess.close()
|
|||
|
ffunction.close()
|
|||
|
fswitch.close()
|
|||
|
fdefine.close()
|
|||
|
fheaderprocess.close()
|
|||
|
fheaderon.close()
|
|||
|
fheaderfunction.close()
|
|||
|
fwrap.close()
|
|||
|
|
|||
|
input()
|