python调用所嵌入C++程序提供的函数

我在做一个c++程序,这个程序嵌入了python,而python脚本有些功能的数据又需要调宿主程序提供的函数来获取,网上搜的大部分都是python调c动态库,调宿主程序提供的函数基本没有说明,捣腾了半天终于搞好。

python嵌入C++就不说了,百度一大堆。

首先先说下C++程序给python提供函数,方法和以dll形式给python提供接口基本类似,主要是最后模块初始化函数稍微不一样。
概括下就是:
1.原先动态库导出的模块初始化函数有个PyMODINIT_FUNC宏声明换成PyObject*,
2.然后在python初始化之前(即Py_Initialize()调用之前)先添加下本次需新增的模块(PyImport_AppendInittab(“PyExt”, &PyInit_PyExt))
3.在py脚本里import PyExt
4.然后脚本里就可以调用PyExt提供的函数了

下面是代码:
PyExt.h


#include "python.h"
static PyObject* PyExt_test(PyObject *self, PyObject *args)
{
	return PyLong_FromLong(190508);
}

static PyMethodDef PyExtMethods[] =
{
	//{'导入进python调用的名字','对应调用的c函数名','函数调用方式','python调用help显示的帮助说明'}
	/*第3个字段用以决定函数的调用方式
	METH_VARARGS:多个形式参数,最常用的玩法
	METH_NOARGS:无参数,常用于输出类函数
	METH_VARARGS|METH_KEYWORDS :同时拥有匿名参数和关键字参数
	*/
	{ "rtn", PyExt_test, METH_NOARGS, NULL },
	{ NULL, NULL, 0, NULL },
};


static PyModuleDef PyExtModule =
{
	PyModuleDef_HEAD_INIT, "PyExt", NULL, -1, PyExtMethods,
	NULL, NULL, NULL, NULL
};

//下面初始化函数是导出c++动态库用的:以便python解释器能够对模块进行正确的初始化,初始化要以init开头,如initp
/*PyMODINIT_FUNC PyInit_PyExt(void)
{
	return PyModule_Create(&Module);
}*/

//这个初始化是python调用宿主程序的导出函数时需要用
static PyObject* PyInit_PyExt(void)
{
	return PyModule_Create(&PyExtModule);
};

main.cpp


#include "PyExt.h"
//python环境初始化
void Init()
{
	PyImport_AppendInittab("PyExt", &PyInit_PyExt);//加载本应用程序给python提供的额外函数 需要在文件里再improt下
	
	Py_Initialize();    // 初始化

	// 将Python工作路径切换到待调用模块所在目录,一定要保证路径名的正确性
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('./python')");

	// 向python中添加参数名的模块
	// 初始化添加的模块

	// 加载模块
	PyObject* pModule = PyImport_ImportModule("main");//此处是python文件名
	if (!pModule) // 加载模块失败
	{
		return;
	}

	// 加载函数
	PyObject* pv = PyObject_GetAttrString(pModule, "testinit");//此处是python文件中的函数名称
	if (!pv || !PyCallable_Check(pv))  // 验证是否加载成功
	{
		return;
	}
	// 设置参数
	PyObject* args = PyTuple_New(2);   // 2个参数
	PyTuple_SetItem(args, 0, Py_BuildValue("i", 8));//0--序号,i表示创建int型变量
	PyTuple_SetItem(args, 1, Py_BuildValue("i", 6));//1--序号,i表示创建int型变量

	PyObject* pRet = PyObject_CallObject(pv, args);

	//将返回值转换为int类型
	int result = 0;
	PyArg_Parse(pRet, "i", &result);//i表示转换成int型变量
	Py_Finalize();
}

main.py

# -*- coding: GB2312 -*-
import string
import os
import PyExt

def testinit(a, b):
    return PyExt.rtn()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值