C++和python混合编程之在python类构造函数中传参方法
零、前言
C++是一门高效率的语言,Python是一门简单易学的脚本语言,现在Python非常火,这两者的强大结合能碰撞出很强大的火花!一起来看看吧!
一、说明
C++项目中用到python相关的知识,这两天研究了一下C++与python的混合编程,网上有很多这方面的介绍,但是怎么使用python类的构造函数中传参的介绍却没有,这里研究一下,分享出来。(C++和python相互调用的相关接口查询https://docs.python.org/2/index.html)
二、测试代码
1、C++代码
/*=================CplusUsePython.h====================*/
#ifndef CPLUSUSEPYTHON_H
#define CPLUSUSEPYTHON_H
#include <Python.h>
#include <string>
using namespace std;
class CplusUsePython
{
public:
CplusUsePython();
~CplusUsePython();
static CplusUsePython* instance()
{
static CplusUsePython instance;
return &instance;
}
// 初始化相关操作
int init(const string pyFilePath, const string pyFileNameNoSuffix);
// C++调用python函数
int CCallFunction(const string pyFuncName, const string message);
// C++调用python类中的函数
int CCallClassFunc(const string pyFuncName, const string name, const int age);
private:
PyObject *pName;
PyObject *pModule;
PyObject *pFunc;
PyObject *pArgs;
PyObject *pClass;
PyObject *pInstance;
};
#endif // CPLUSUSEPYTHON_H
/*=================CplusUsePython.cp====================*/
#include "CplusUsePython.h"
#include <sstream>
CplusUsePython::CplusUsePython()
{
}
CplusUsePython::~CplusUsePython()
{
if (Py_IsInitialized()) {
if (pName) Py_DECREF(pName);
if (pArgs) Py_DECREF(pArgs);
if (pModule) Py_DECREF(pModule);
if (pFunc) Py_DECREF(pFunc);
if (pClass) Py_DECREF(pClass);
if (pInstance) Py_DECREF(pInstance);
Py_Finalize();
}
}
//************************************
// 函数名称: init
// 函数说明:初始化相关操作
// 返 回 值: int
// 参 数: const string pyFilePath
// 参 数: const string pyFileNameNoSuffix
// 作 者:ISmileLi
// 作成日期:2018/11/25
// 修改记录:
//************************************
int CplusUsePython::init(const string pyFilePath, const string pyFileNameNoSuffix)
{
int ret = 0;
if (pyFilePath.empty() || pyFileNameNoSuffix.empty())
return -1;
Py_Initialize();
pName = NULL;
pModule = NULL;
pFunc = NULL;
pArgs = NULL;
pClass = NULL;
pInstance = NULL;
// 判断初始化是否成功
if (!Py_IsInitialized())
return -2;
// 调用python中需要使用的模块
ret = PyRun_SimpleString("import sys");
if (ret != 0)
{
// 导入失败,关闭python调用
Py_Finalize();
return -3;
}
// 导入python文件的相关操作
if (ret == 0)
{
stringstream strpycmd;
strpycmd << "sys.path.append('" << pyFilePath << "')";
ret = PyRun_SimpleString(strpycmd.str().c_str());
}
if (ret != 0)
{
Py_Finalize();
return -4;
}
pName = PyString_FromString(pyFileNameNoSuffix.c_str());
if ((pModule = PyImport_Import(pName)) == NULL || pName == NULL)
{
Py_Finalize();
return -5;
}
return 0;
}
//************************************
// 函数名称: CCallFunction
// 函数说明:C++调用python中的函数
// 返 回 值: int
// 参 数: const string pyFuncName
// 参 数: const string message
// 作 者:ISmileLi
// 作成日期:2018/11/25
// 修改记录:
//************************************
int CplusUsePython::CCallFunction(const string pyFuncName,const string message)
{
if (pyFuncName.empty() || message.empty())
{
return -1;
}
pFunc = PyObject_GetAttrString(pModule, pyFuncName.c_str());
if(!pFunc)
{
return -2;
}
// 调用python函数,s表示传入参数是字符串类型
PyObject *pRet = PyObject_CallFunction(pFunc, "s", (char*)message.c_str());
if(pRet)
{
Py_DECREF(pRet);
}
else
{
return -3;
}
return 0;
}
//************************************
// 函数名称: CCallClassFunc
// 函数说明:C++调用python类中的函数
// 返 回 值: int
// 参 数: const string pyFuncName
// 参 数: const string name
// 参 数: const string age
// 作 者:ISmileLi
// 作成日期:2018/11/25
// 修改记录:
//************************************
int CplusUsePython::CCallClassFunc(const string pyFuncName,const string name, const int age)
{
if (pyFuncName.empty() || name.empty() || age <= 0)
{
return -1;
}
// 向Python传参数是以元组(tuple)的方式传递的
pArgs = PyTuple_New(2);
// PyObject* Py_BuildValue(char *format, ...) 将C++的变量转换成一个Python对象
// s 表示字符串,i 表示整型变量,f 表示浮点数
PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", name.c_str()));
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", age));
// 增加支持调用类中方法的操作
pClass = PyObject_GetAttrString(pModule,"ISmileLi"); // DrawPic为类的名字
if(!pClass)
{
return -2;
}
// 传入python构造函数中的两个参数
pInstance = PyInstance_New(pClass,pArgs,NULL);
if(!pInstance)
{
return -3;
}
// 调用类中的函数
pFunc = PyObject_CallMethod(pInstance,(char*)pyFuncName.c_str(),NULL,NULL);
if(!pFunc)
{
return -4;
}
return 0;
}
/*=================main.c================*/
#include <Python.h>
#include <iostream>
#include <string>
#include "CplusUsePython.h"
using namespace std;
int main ()
{
// C++和python相互调用的相关接口查询https://docs.python.org/2/index.html
string pyFilePath = "/work/test/testC++/test_C_use_Python";
int ret = CplusUsePython::instance()->init(pyFilePath,"ISmileLi");
if(ret != 0)
{
cout << "init failure!" << endl;
}
ret = CplusUsePython::instance()->CCallFunction("print_message","this is test C++ use python!");
ret = CplusUsePython::instance()->CCallClassFunc("print_name","LiSa",18);
ret = CplusUsePython::instance()->CCallClassFunc("print_age","LiSa",18);
ret = CplusUsePython::instance()->CCallClassFunc("print_name_age","LiSa",18);
return 0;
}
2、python代码
#filename: ISmileLi.py
# -*- coding: utf-8 -*-
class ISmileLi:
def __init__(self,name,age):
self.name = name
self.age = age
def print_name(self):
print("===in function print_name===")
print("name:",self.name)
def print_age(self):
print("===in function print_age===")
print("age:",self.age)
def print_name_age(self):
print("===in function print_name_age===")
print("name:%s age:%d" % (self.name,self.age))
def print_message(message):
print("===in function print_message===")
print("message:",message)
三、运行结果
说明:由于我也不擅长python,如有错误欢迎指正。
本文为博主原创文章,未经博主允许请勿转载!作者:ISmileLi