环境配置
在你的python安装目录下找到include和libs文件夹,由于我安装的是anaconda所以我的python是在anaconda安装目录下,若是直接安装的python则就找python安装目录
然后将这两个文件夹的路径导入你的VS 项目属性的vc++目录里,include导入到包含目录,libs导入到库目录。注意你配置的是debug模式下还是release模式下,需要对应起来 。
在链接器->输入->附加依赖项中添加python38.lib,该文件就在你刚刚找到的libs文件夹里。
注意
在release下添加的是python38.lib,在debug下添加python38_d.lib,由于我用的anaconda里没有python38_d.lib所以我用的是release模式
导入第三方库
如果python中导入第三方库,需要下图中的Dlls和Lib放入vs项目中的执行文件相同目录
再将python38.dll,python3.dll也一同放进该目录
1)python自身模块的优先级高于你自己定义的模块,最好不要起test.py这样的名字,不然找不到自定义脚本
2)脚本内的方法名称不要与python自身模块一致,不然找不到自定义方法
3)当安装两个版本python情况可以将需要使用python版本的环境变量配置放置在另一个版本(将环境变量位置上移调整)
4)编写的python代码文件也放进vs项目中的执行文件相同目录
c++代码
void python_butter(char* filter, int N, double Wn1, double Wn2, double col_fre, double* a_z, double* b_z)
{
//以下为c++调用python脚本的步骤程序
Py_Initialize();//初始化python解释器
PyRun_SimpleString("import sys");
//添加模块路径 该地址为你复制到c++工程目录下的Lib里的第三方库所在地址,这是我的python脚本用到的scipy库的所在地址
PyRun_SimpleString("sys.path.append('d:/yjygy/desktop/Butterworth/Butterworth/x64/Release/Lib/site-packages/')");
//导入模块
PyObject* pModule = nullptr;
pModule = PyImport_ImportModule("butter_c");//导入py文件,参数为文件名
if (!pModule)
{
cout << " call module failed. " << endl;
}
cout << " call module successfully ! " << endl;
//声明变量,初始化;
PyObject* pv = NULL;
//调用函数名;
pv = PyObject_GetAttrString(pModule, "main_function");
PyObject* args = PyTuple_New(5); // 新建需要传入参数并定义个数,这里定义了5个
PyObject* arg0 = Py_BuildValue("s", filter);//滤波器类型参数
PyObject* arg1 = Py_BuildValue("i", N);//阶数
PyObject* arg2 = Py_BuildValue("d", Wn1);//上限截止频率
PyObject* arg3 = Py_BuildValue("d", Wn2);//下限截止频率
PyObject* arg4 = Py_BuildValue("d", col_fre);//采样频率
//将arg1配置为arg带入的第一个参数
PyTuple_SetItem(args, 0, arg0);
//将arg1配置为arg带入的第二个参数
PyTuple_SetItem(args, 1, arg1);
PyTuple_SetItem(args, 2, arg2);
PyTuple_SetItem(args, 3, arg3);
PyTuple_SetItem(args, 4, arg4);
PyObject* pRet = PyObject_CallObject(pv, args);//返回pyhon函数的返回数据
int list_len = PyObject_Size(pRet);//获取返回结果长度
printf("list_len=%d\n", list_len);
for (int i = 0; i < list_len; i++)
{
PyObject* list_item = PyList_GetItem(pRet, i);//根据下标取出python列表中的元素
double result = PyFloat_AsDouble(list_item);//pyhon里的float类型转化为c++里的double类型
if (i < list_len / 2)
{
a_z[i] = result;
}
else
{
b_z[i - (list_len / 2)] = result;
}
//printf("%.9f\n", result);//打印并保留9位小数
}
//打印ab系数--------------------------------------------------------------------------------------------------
for (int ii = 0; ii < list_len/2; ii++)
{
printf("a[%d]=%.9f \t b[%d]=%.9f\n", ii, a_z[ii], ii, b_z[ii]);
}
//------------------------------------------------------------------------------------------------------------
Py_Finalize();
}
python代码
#butter_c.py
from scipy import signal
def main_function(i,N,Wn1,Wn2,col_fre):
# 带通滤波器
if i=='bandpass':
b,a=signal.butter(N,[2*Wn1/col_fre,2*Wn2/col_fre],'bandpass' )
# 带阻滤波器
if i=='bandstop':
b,a=signal.butter(N,[2*Wn1/col_fre,2*Wn2/col_fre],'bandstop' )
# 低通滤波器
if i=='lowpass':
b,a=signal.butter(N,2*Wn1/col_fre,'lowpass' )
# 高通滤波器
if i=='highpass':
b,a=signal.butter(N,2*Wn1/col_fre,'highpass' )
c=a.tolist()+b.tolist()
return c
注意:
由于之前添加模块路径一直没弄对,导致程序报错导入第三方库失败所以
PyRun_SimpleString("sys.path.append('./')");
十分重要,路径一定要对,该路径为你复制到c++工程目录下的Lib里的第三方库所在路径。
如果没用python的其他库只是用了python的基础函数则这一步可省略
可参考链接:
https://blog.csdn.net/m0_38125278/article/details/87191971