一文入门C语言与Python互调用法

Python调用C程序https://blog.csdn.net/qq_22751305/article/details/105361916?spm=1001.2014.3001.5501

C/C++调用Python函数

包含常规数值的传入传出,数组的传入传出

针对模块导入,返回空指针的问题,也有说明,见代码注释。

以win10为例。默认已经安装好Python环境。注意:需配置PYTHONHOME和PYTHONPATH环境变量,否则运行时可能会报错。

在vs2015上配置Python,这个比较简单。步骤如下:

1. 系统环境变量PATH中追加路径:

            D:\ProgramData\Anaconda3\envs\py39;

            D:\ProgramData\Anaconda3\envs\py39\Library\bin

2. 在工程属性表中添加include目录和库目录,添加附加依赖项:

          

 

至此,环境配置好了。

C调用Python函数

 python代码如下python_test.py:

import cv2
import numpy as np

def list_test(array, N):
    print('test list')
    print(array)
    print(N)
    return [1.3,2,3,4]


def add(a,b):
    print('a+b=')
    return a+b

def show_img():
    im = cv2.imread('qq.jpg')
    cv2.imshow('qq',im)
    cv2.waitKey(1)

C/C++代码如下,见注释。

#include<iostream>
#include "opencv2/opencv.hpp"
//#include "D:/ProgramData/Anaconda3/envs/py39/include/python.h"
//#pragma comment(lib, "D:\\ProgramData\\Anaconda3\\envs\\py39\\libs\\python39.lib") 
//若在编译器设置了include和lib路径以上两行可以转化为
#include<Python.h>

int main()
{
	// 初始化python
	Py_Initialize();
	
	if (!Py_IsInitialized())
	{
		std::cout << "python initialized failed\n";
	}
	
	//添加python_test.py文件所在路径
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('D:/workspace/C_python/C_python/')");

	//导入模块,不带后缀
	//若python_test.py文件路径不对、python环境不对、python_test.py中存在错误,
	// 都会导致pModule为空指针。
	PyObject* pModule = PyImport_ImportModule("python_test");
	if (!pModule)
	{
		std::cout << "Python get module failed." << std::endl;
	}
	PyObject* pDict = PyModule_GetDict(pModule);
	if (!pDict)
	{
		std::cout << "Python get dict failed." << std::endl;
	}
	PyObject *pFunc = PyDict_GetItemString(pDict, "show_img");
	PyObject_CallObject(pFunc,NULL);

	pFunc = PyDict_GetItemString(pDict, "add");
	//参数进栈
	PyObject *pArgs = PyTuple_New(2);
	//下面的是重点了,从c/c++传参数到Python中时需要用到一个函数,原型为
	//PyObject* Py_BuildValue(char *format,……)
	//类似c的printf,但格式不同。常见的格式有
	//s 字符串
	//i 整形变量
	//f 浮点型
	//o Python对象
	PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 3));
	PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 4));
	//调用Python函数
	PyObject *pRetVal = PyObject_CallObject(pFunc, pArgs);
	printf("function return value: %d\n", PyLong_AsLong(pRetVal));
	printf("function return value: %f\n", PyFloat_AsDouble(pRetVal));

	// C向python函数传入数组
	PyObject *pList = PyList_New(100);
	for (int i = 0; i < 100; i++)
	{
		PyList_SetItem(pList, i, Py_BuildValue("i", i));
	}
	PyTuple_SetItem(pArgs, 0, pList);
	PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 100));
	pFunc = PyDict_GetItemString(pDict, "list_test");
	PyObject* pRes = PyObject_CallObject(pFunc, pArgs);
	// 获取返回值list,并解析
	int N = PyList_Size(pRes);
	printf("the res N: %d\n", N);
	for (int i = 0; i < N; i++)
	{
		printf("%f, ",PyFloat_AsDouble( PyList_GetItem(pRes, i))); 
	}

	Py_Finalize(); //释放资源
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值