C++调用Python的工具类

最近参考了别人的C++调用python方法,我把它封装成了一个pyinit的工具类。这样可以使我们在主函数中,只需很少的几步就可以完成python的调用。


pyinit.h

#ifndef _PYINIT_H
#define _PYINIT_H

#include <Python.h>

typedef PyObject py_object;    //这个替换是我的个人习惯,我很少用大写的

class pyinit {
public:
	pyinit();
	~pyinit();
public:
	//执行一段python代码,就好像__main__函数中执行一样,默认是导入sys,和路径
	void pyrun_simple_string(const char* s1 = "import sys",
                             const char* s2 = "sys.path.append('./')");  //执行一段python代码,就好像__main__函数中执行一样,默认是导入sys,和路径
	void load_py_script(const char* name); //加载python脚本,获得name,module,dict   
	void find_function(const char* f);    //查找要执行的函数
	void set_item(const char* type);    //设置参数
	void call_function();            //调用函数
private:
	pyinit(const pyinit& other);
	pyinit& operator=(const pyinit& other);
private:
	py_object* name_;      //文件名
	py_object* module_;    //模块
	py_object* dict_;      //想到与Python模块对象的_dict_属性,得到模块名称空间下的字典对象	
	py_object* func_;      //要执行的函数
	py_object* args_;      //参数
};



pyinit.cpp

#include "pyinit.h"

pyinit::pyinit()
	: name_(NULL), 
	  module_(NULL), 
	  dict_(NULL),
	  func_(NULL),
	  args_(NULL)     //由于都是指针,所以初值全部赋空
{
	Py_Initialize();         //初始化,无返回值
	assert(Py_IsInitialized());   //靠着这来判断是否初始化成功
}

pyinit::~pyinit()
{
	Py_DECREF(name_);    //减少引用计数
	Py_DECREF(args_);
	Py_DECREF(module_);
	Py_Finalize();        //销毁
	name_ = NULL;
	module_ = NULL;
	dict_ = NULL;
	func_ = NULL;
	args_ = NULL;
}

void pyinit::pyrun_simple_string(const char* s1, const char* s2)  //执行s1,s2,如improt sys
{
	PyRun_SimpleString(s1);
	PyRun_SimpleString(s2);
}

void pyinit::load_py_script(const char* name)   //执行脚本,得到名字,模块,字典属性
{
	assert(name != NULL);
	name_ = PyString_FromString(name);
	module_ = PyImport_Import(name_);
	assert(module_ != NULL);
	dict_ = PyModule_GetDict(module_);
	assert(dict_ != NULL);
}

void pyinit::find_function(const char* f)      //查找函数,f是函数名
{
	assert(f != NULL);
	func_ = PyDict_GetItemString(dict_, f);  
	assert(func_ != NULL);
	assert(PyCallable_Check(func_));   //检查函数是否可调
}

void pyinit::set_item(const char* name)  //设置参数
{
	assert(name != NULL);
	args_ = PyTuple_New(1);    //一个参数就new一个元组
	PyTuple_SetItem(args_, 0, Py_BuildValue("s", name));   //args_是一个元组参数,
}

void pyinit::call_function()   //调用函数
{
	PyObject_CallObject(func_, args_);
}



测试文件:

测试文件使用用来解析xml的,形式已经给出。

#include "pyinit.h"
#include <iostream>

int main()
{
	pyinit  py;
	py.pyrun_simple_string();
	py.load_py_script("resolver");
	py.find_function("Parse_XML");
    py.set_item("movies.xml");
	py.call_function();
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值