首页 > 编程语言 >功能不够用?使用C++编写通达信插件及接入Python(二)

功能不够用?使用C++编写通达信插件及接入Python(二)

时间:2023-04-17 16:44:34浏览次数:52  
标签:插件 Python int float list C++ python DataLen result

参考:https://zhuanlan.zhihu.com/p/613157262

一、准备工作(参考上一篇)

安装 VS2019 

安装pycharm

下载  http://help.tdx.com.cn/book.asp 《通达信DLL函数编程规范.rar》

二、下载python3.x的32位版本,http://www.python.org,随便找个32位版就行了。

我准备下载Windows embeddable package (32-bit),然而下载速度感人,于是参考https://blog.csdn.net/m0_64336780/article/details/123534308

从 https://mirrors.huaweicloud.com/python/ 下载了   python-3.11.3.exe 安装

由于我已经安装了python 64 位的,所以安装后,要调整环境变量,将32位的环境变量调到上面,就切换成32位了。需要63位时,再将64位的环境变量调整到上面即可。

三、从   通达信DLL函数编程规范  里的项目开始

1.修改VS2019,勾选  windows10 SDK

2. 用Visual studio 打开 “TestPluginTCale.dsw”文件

出现“评审项目和解决方案更改”  ,直接 确定

出现迁移报告,存在错误

3.解决BUG - 修改项目属性

在解决方案资源管理器中,项目的  TestPluginTCale上右键 属性  

在弹出框的  配置属性  c/c++  常规  中,将  “调试信息格式”的选项更改为“程序数据库(/Zi)”

               在 配置属性  c/c++  代码生成  中 “启用最小重新生成”设为“否(/Gm-)”

               在 配置属性  c/c++  代码生成  中 “启用函数级链接”设为“是(/Gy)”

               在 配置属性  链接器  常规   附加库目录 

             输入 D:\Python\python31132\libs  (根据你的32位python安装位置确定)之后,值变为:D:\Python\python31132\libs;%(AdditionalLibraryDirectories)

              如果添加后,vs报错,说什么python3x_d找不到,那就在安装目录下的libs(不是lib)里找到python3x.lib,复制一份改个名,改成vs要求的文件名就行了。总之,vs说差什么文件,改成vs要求的文件名就可以了。

四、改写TCalcFuyncSets.cpp如下:

#include "stdafx.h"

#include "TCalcFuncSets.h"

#include "Python.h" //严重注意,一定要include这个。

//生成的dll请拷贝到通达信安装目录的T0002/dlls/内,再在公式管理器进行绑定

//有人老是无法正常绑定,这里给出两种解决方案,任选其一,本人喜欢第二种

//1、不运行快捷方式,直接点开通达信目录里的执行文件

//2、运行快捷方式,但需要将快捷方式里的起始位置清空

void CallFunction(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc, char* funcName)

{

	//填上自己的32位python安装目录,当然,你的python也可以直接装在这个目录下。

	Py_SetPythonHome(L"C:\\Python31132"); //用这个版本的python来执行python文件

	Py_Initialize(); //初始化python接口



	//初始化使用的变量

	PyObject* pModule = NULL;

	PyObject* pFunc = NULL;

	PyObject* pName = NULL;



	//获得绝对路径,保证可以访问到 .py文件

	//这里需要注意的时候,运行通达信时,找到的路径是通达信的安装路径,所以需要把子路径补充进去

	PyRun_SimpleString("import os,sys");

	PyRun_SimpleString("sys.path.append(os.getcwd()+ '/T0002/dlls/')");



	//当前的测试python文件名是TDXPYDLL.py,只需要写文件的名称就可以了。也可以换个名字,但需要把名字改了。

	pModule = PyImport_ImportModule("TDXPYDLL");



	//获取调用的函数

	pFunc = PyObject_GetAttrString(pModule, funcName);



	//定义一个与数组等长的PyList对象数组

	PyObject* HList = PyList_New(DataLen);

	PyObject* LList = PyList_New(DataLen);

	PyObject* CList = PyList_New(DataLen);



	//定义一个元组,有四个变量的参数元组

	PyObject* paramTuple = PyTuple_New(4);



	//PyList对象的每个元素赋值PyList_Size(HList),以便传入价格序列

	for (int i = 0; i < DataLen; i++)

	{

		PyList_SetItem(HList, i, Py_BuildValue("f", pfINa[i]));

		PyList_SetItem(LList, i, Py_BuildValue("f", pfINb[i]));

		PyList_SetItem(CList, i, Py_BuildValue("f", pfINc[i]));

	}



	//向python传参数

	PyTuple_SetItem(paramTuple, 0, Py_BuildValue("i", DataLen));//第一个参数

	PyTuple_SetItem(paramTuple, 1, HList); //1:表示序号。第二个参数。

	PyTuple_SetItem(paramTuple, 2, LList); //2:表示序号。第三个参数。

	PyTuple_SetItem(paramTuple, 3, CList); //3:表示序号。第四个参数。



	//使用C++的python接口调用该函数

	PyObject* pReturn = PyObject_CallObject(pFunc, paramTuple);



	if (pReturn) //类型检查

	{

		for (int i = 0; i < DataLen; i++)

		{

			//PyObject *Item = PyList_GetItem(pReturn, i);//获取List对象中的每一个元素

			float result;

			PyArg_Parse(PyList_GetItem(pReturn, i), "f", &result);//f表示转换成浮点变量

			pfOUT[i] = result;

		}

	}

	////用完接口得放掉,呼应前面的Py_Initialize();

	Py_Finalize();



}



void TestPlugin1(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc)

{

	CallFunction(DataLen, pfOUT, pfINa, pfINb, pfINc, "TestPlugin1");

}



void TestPlugin2(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc)

{

	CallFunction(DataLen, pfOUT, pfINa, pfINb, pfINc, "TestPlugin2");

}





void TestPlugin3(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc)

{

	CallFunction(DataLen, pfOUT, pfINa, pfINb, pfINc, "TestPlugin3");

}





void TestPlugin4(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc)

{

	CallFunction(DataLen, pfOUT, pfINa, pfINb, pfINc, "TestPlugin4");

}



void TestPlugin5(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc)

{

	CallFunction(DataLen, pfOUT, pfINa, pfINb, pfINc, "TestPlugin5");

}



void TestPlugin6(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc)

{

	CallFunction(DataLen, pfOUT, pfINa, pfINb, pfINc, "TestPlugin6");

}



//加载的函数,这里的序号和上面函数对应,这只是绑了六个,想多绑的自己加

PluginTCalcFuncInfo g_CalcFuncSets[] =

{

{1,(pPluginFUNC)&TestPlugin1},

{2,(pPluginFUNC)&TestPlugin2},

{3,(pPluginFUNC)&TestPlugin3},

{4,(pPluginFUNC)&TestPlugin4},

{5,(pPluginFUNC)&TestPlugin5},

{6,(pPluginFUNC)&TestPlugin6},

{0,NULL},

};



//导出给TCalc的注册函数

BOOL RegisterTdxFunc(PluginTCalcFuncInfo** pFun)

{

	if (*pFun == NULL)

	{

		(*pFun) = g_CalcFuncSets;

		return TRUE;

	}

	return FALSE;

}

  结果提示没头文件,python.h

参考:https://blog.csdn.net/JLinkTwo/article/details/87917504  用   pip install python-dev  安装

再参考:https://blog.csdn.net/weixin_44575152/article/details/114186758     对 配置属性  VC++目录   外部包含目录   进行编辑,  加入了  python.h所在目录: D:\Python\python31132\include

生成解决方案
又提示: 无法打开文件“python311_d.lib

于是将D:\Python\python31132\libs下的 python311.lib 复制 为  python311_d.lib

终于成功了

到了这里, Dll写完了,编译成32位TestPluginTCale.dll放到T0002/dlls目录里。然后创建一个TDXPYDLL.py,该文件同样需要放在T0002/dlls内。

def TestPlugin1(N: int, H: list, L: list, C: list):
    for i in range(1, N):
        result[i] = i
    return result
def TestPlugin2(N: int, H: list, L: list, C: list):
    for i in range(1, N):
        result[i] = i
    return result
def TestPlugin3(N: int, H: list, L: list, C: list):
    for i in range(1, N):
        result[i] = i
    return result
def TestPlugin4(N: int, H: list, L: list, C: list):
    for i in range(1, N):
        result[i] = i
    return result
def TestPlugin5(N: int, H: list, L: list, C: list):
    for i in range(1, N):
        result[i] = i
    return result
def TestPlugin6(N: int, H: list, L: list, C: list):
    for i in range(1, N):
        result[i] = i
    return result

按上一篇 绑定DLL,写demo公式,结果通达信死机

后来发现 dll 源文件 中有一句忘记改了:

Py_SetPythonHome(L"C:\\Python31132"); //用这个版本的python来执行python文件

改为Py_SetPythonHome(L"D:\\Python\\python31132");

重新生成dll,替换,不要从快捷方式而是从所在目录中启动TdxW.exe,看似成功了,python脚本似乎也运行了。然而得不到输出

又参照网贴,将TestPlugin2改为如下代码:

def TestPlugin2(N: int, H: list, L: list, C: list):
    result=[]
    for i in range(1, N):
        temp = i * 6.0
        result.append(temp)    
    return result

  终于成功了

说明:在python代码中,可以import os  

用os.mkdir('你的目录')在通达信运行目录中生成文件夹

更明显地看到效果。

 

标签:插件,Python,int,float,list,C++,python,DataLen,result
From: https://www.cnblogs.com/pu369/p/17319287.html

相关文章

  • Python数据分析方向第三方库推荐!
    在Python的应用范围中,数据分析是一个非常不错的就业方向,发展前景好、需求市场大,也成为很多人的首选方向,因此Python也提供了许多数据分析的第三方库。那么Python数据分析第三方库有哪些?这篇文章为大家详细介绍一下。1、PandasPandas是Python强大、灵活的数据分析和探索......
  • jQuery Templates模板插件
    jQuery团队提供了一个模板插件,但非常可惜的是jquery团队放弃对其维护,我们对其方法和语法进行简单简绍源码官方的网址:http://api.jquery.com/category/plugins/templates文档的网址:http://api.jquery.com/category/plugins/templates使用该插件必须先引入对应js //依赖jquery<sc......
  • 沉浸式翻译 插件推荐 同时显示中文和英文
    安装https://immersive-translate.owenyoung.com/installation特殊浏览器用油猴安装。我用的双核浏览器,内核比较老,就只能用油猴的方式装了,非常好用。......
  • 【python-docx】添加表格、合并单元格、设置样式
    1.表格1.1添加表格添加表格很简单,只需要调用一下add_table()即可,返回一个Table对象,参数可以指定行、列、样式fromdocximportDocumentdoc=Document()#添加一个5行3列的表格,样式是网格实线table=doc.add_table(5,3,style="TableGrid")doc.save('./test.docx')1.2添......
  • C#模拟C++模板特化对类型的值的支持
    概述C++的模板相比于C#的泛型,有很多地方都更加的灵活(虽然代价是降低了编译速度),比如C++支持变长参数模板、支持枚举、int等类型的值作为模板参数。C++支持枚举、int等类型的值作为模板参数,为C++的静态多态编程提供了很好的帮助,比如根据枚举值编译期确定某个对象的行为策略等(下文......
  • 盘点Python内置函数sorted()高级用法实战
    今日鸡汤清川带长薄,车马去闲闲。大家好,我是Python进阶者。一、前言前几天在Python钻石交流群有个叫【emerson】的粉丝问了一个Python排序的问题,这里拿出来给大家分享下,一起学习下。其实这里【瑜亮老师】、【布达佩斯的永恒】等人讲了很多,只不过对于基础不太好的小伙伴们来说,还是有......
  • vscode c++ 配置
    //vscodeC++环境配置//三个配置文件c_cpp_properties.json{"configurations":[{"name":"Win32","includePath":["${workspaceFolder}/**"],......
  • python中列表常见的操作方法
    一、添加元素的方法1.append()方法#l.append()用于在列表末尾添加新的对象,返回值:该方法无返回值,但是会修改原来的列表l=[1,2,3,4,5]l1=[6,7,8]l2={"age":"12"}l3='年后,nihao'l4=('height','name')#增加列表l.append(l1)print(l)#......
  • python s12 day13 JavaScript、Dom和jQuery
    1.JavaScriptJavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处理。1、JavaScript代码存在形式<!--方式一--><scripttype"text/javascript"src="JS文件"></script>......
  • m1--安装python2
    brewinstallpyenv##这样更快如果在国外这步可以跳过cd~/.pyenvwgethttps://www.python.org/ftp/python/2.7.18/Python-2.7.18.tar.xzmkdircachecpPython-2.7.18.tar.xzcache##安装pyenvinstall2.7.18exportPATH="$(pyenvroot)/shims:${PATH}"pyenvglobal......