python c++ 混合编程_【Python】C++ & Python 混合编程(1)-- C++使用Python

C++环境配置

Windows下

以VS为例,配置包含目录和库目录

SouthEast

图1. 目录设置

编译平台(x64和win32)需要与Python版本一致

debug模式下需要将python27.lib重命名为python27_d.lib

Linux下

以QT为例,配置包含目录和库目录

// xxx.pro

INCLUDEPATH += -I /usr/include/python2.7/

LIBS += -L /usr/lib/python2.7/config-x86_64-linux-gnu/ -lpython2.7

调用示例

分别调用python函数和python类

1)Python 实现具体方法

假设脚本名字为 pyTest.py

#!/usr/bin/env python

# -*- coding: utf-8 -*-

def add_it(a, b):

print '[python] add %d and %d'%(a, b)

return a+b

class cladd:

def __init__(self, param1, param2):

print 'param1: ',param1

print 'param2: ',param2

def add_it(self, a, b):

print '[python-class] add %d and %d'%(a, b)

return a+b

2)C++直接调用 pyTest.py 的函数 add_it

#include "stdafx.h"

#include "iostream"

#include "Python.h"

using namespace std;

void main()

{

// 初始化

Py_Initialize();

// 加载模块

PyObject* moudleName = PyString_FromString("pyTest");

PyObject* pModule = PyImport_Import(moudleName);

if(!pModule){

cout << "Python get moudle failed" <

return;

}

cout << "Python get moudle succeed" <

// 加载函数

PyObject* pFunc = PyObject_GetAttrString(pModule, "add_it");

if(!pFunc || !PyCallable_Check(pFunc)){

cout << "can not find function"<

return;

}

cout << "get function succeed" <

// 设置参数

PyObject* args = PyTuple_New(2);

PyObject* arg1 = PyInt_FromLong(4);

PyObject* arg2 = PyInt_FromLong(3);

PyTuple_SetItem(args, 0, arg1);

PyTuple_SetItem(args, 1, arg2);

// 调用函数

PyObject* pRet = PyObject_CallObject(pFunc, args);

// 获取返回

if(pRet){

long result = PyInt_AsLong(pRet);

cout << "result: "<

}

// 释放资源

Py_Finalize();

}

3)C++ 调用 pyTest.py 的 cladd 类

void main()

{

// 初始化

Py_Initialize();

// 加载模块

PyObject* moudleName = PyString_FromString("pyTest");

PyObject* pModule = PyImport_Import(moudleName);

if(!pModule){

cout << "Python get moudle failed" <

return;

}

cout << "Python get moudle succeed" <

// 加载类

PyObject* pClass = PyObject_GetAttrString(pModule, "cladd");

if(!pClass){

cout << "can not find class"<

return;

}

cout << "get class succeed" <

// 创建类实例

PyObject* args = PyTuple_New(2);

PyObject* arg1 = Py_BuildValue("s", "da");

PyObject* arg2 = Py_BuildValue("s", "dada");

PyTuple_SetItem(args, 0, arg1);

PyTuple_SetItem(args, 1, arg2);

PyObject* pInstance = PyInstance_New(pClass, args, NULL);

// 调用方法

PyObject* pRet = PyObject_CallMethod(pInstance, "add_it", "(ii)", 4, 3);

// 获取返回

if(pRet){

long result = PyInt_AsLong(pRet);

cout << "result: "<

}

// 释放资源

Py_Finalize();

}

细节

所有Python元素在 C里都是 PyObject 对象

Python 类型 XXX 和 C 类型 YYY 的转换使用 PyXXX_AsYYY 和 PyXXX_FromYYY

基本流程是:

1)初始化 -> Py_Initialize()

2)加载模块 -> PyImport_Import(PyString_FromString(“python 脚本名”))

3)加载函数/类 -> PyObject_GetAttrString(…)

4)创建类实例 -> PyInstance_New(…)

5)设置参数

6)调用函数/方法 -> PyObject_CallObject(…) / PyObject_CallMethod(…)

7)解除对象引用(以便python垃圾回收) -> Py_DECREF(PyObject*)

8)释放资源 -> Py_Finalize()

设置参数:

Python的参数实际上是元组,因此传参实际就是构造一个合适的元组

1)使用 PyTuple_New 创建元组,并用 PyTuple_SetItem 设置元组值

PyObject* args = PyTuple_New(3);

PyObject* arg1 = Py_BuildValue("i", 100); // 整数参数

PyObject* arg2 = Py_BuildValue("f", 3.14); // 浮点数参数

PyObject* arg3 = Py_BuildValue("s", "hello"); // 字符串参数

PyTuple_SetItem(args, 0, arg1);

PyTuple_SetItem(args, 1, arg2);

PyTuple_SetItem(args, 2, arg3);

2)直接使用 Py_BuildValue 构造元组

// (ifs)表示 int、float、string 3个值

PyObject* args = Py_BuildValue("(ifs)", 100, 3.14, "hello");

Python 脚本名称不要设为“test.py”,会出现错误,原因未知

Linux下 C 代码里还需指定 Python 脚本的路径,否则会找不到模块(windows下会默认在工程目录下找)

...

Py_Initialize(); // 初始化

// 指定 python 脚本的目录

string path = string("sys.path.append(\'/home/path-to-python-file\')");

const char* cstr_cmd = path .c_str();

PyRun_SimpleString("import sys");

PyRun_SimpleString(cstr_cmd);

// 加载模块

...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值