C++ 调用python

#include <Python.h>
#include <arrayobject.h>
static PyGILState_STATE gstate;
int  InitPython() {
	//在使用Python系统前,必须使用Py_Initialize对其  
	//进行初始化。它会载入Python的内建模块并添加系统路  
	//径到模块搜索路径中。这个函数没有返回值,检查系统  
	//是否初始化成功需要使用Py_IsInitialized。  
	Py_Initialize();
	import_array();
	// 检查初始化是否成功  
	if (!Py_IsInitialized()) {
		return ERROR_CODE(0x001);
	}
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('./')");

	PyEval_InitThreads();
	PyEval_ReleaseThread(PyThreadState_Get());

	return 0;
}
//关闭Python  
int UnitPython() {
	PyGILState_Ensure();
	Py_Finalize();
	return 0;
}
/// <summary>
/// 加载Python脚本
/// </summary>
/// <param name="pyName">当前目录下的python脚本文件名,不加后缀.py</param>
/// <param name="pyPath">当前python脚本路径为 sys.path.append('文件路径') PyRun_SimpleString("sys.path.append('./')")</param>
/// <returns>返回对应的Module</returns>
void* LoadPython(char* pyName, char* pyPath) {
	gstate = PyGILState_Ensure(); //申请获取GIL

	PyObject* pyModule = NULL;

	Py_BEGIN_ALLOW_THREADS;
	Py_BLOCK_THREADS;


	PyRun_SimpleString(pyPath);
	//PyRun_SimpleString("print(sys.path)");
	//载入名为pyName的脚本  
	pyModule = PyImport_ImportModule(pyName);
	if (!pyModule) {
		return NULL;
	}

	Py_UNBLOCK_THREADS;
	Py_END_ALLOW_THREADS;
	PyGILState_Release(gstate);

	return (void*)pyModule;
}
/// <summary>
/// 释放Python脚本
/// </summary>
/// <param name="pyModule">LoadPython 返回值</param>
/// <returns>0,成功,非0,失败</returns>
int unLoadPyThon(void* pyModule) {
	gstate = PyGILState_Ensure(); //申请获取GIL
	Py_BEGIN_ALLOW_THREADS;
	Py_BLOCK_THREADS;

	Py_DECREF(pyModule);

	Py_UNBLOCK_THREADS;
	Py_END_ALLOW_THREADS;
	PyGILState_Release(gstate);
	return 0;
}
/// <summary>
/// 获取Python字典
/// </summary>
/// <param name="pyModule">LoadPython 返回值</param>
/// <returns>返回对应的Dict</returns>
void* GetPDict(void* pyModule) {
	gstate = PyGILState_Ensure(); //申请获取GIL
	PyObject* pDict = NULL;

	Py_BEGIN_ALLOW_THREADS;
	Py_BLOCK_THREADS;

	pDict = PyModule_GetDict((PyObject*)pyModule);
	if (!pDict) {
		return NULL;
	}
	Py_UNBLOCK_THREADS;
	Py_END_ALLOW_THREADS;
	PyGILState_Release(gstate);
	return (void*)pDict;
}
/// <summary>
/// 获取Python方法
/// </summary>
/// <param name="pDict">GetPDict 返回值</param>
/// <param name="funcName">方法名字</param>
/// <returns>返回对应的Func</returns>
void* GetPFunc(void* pDict, char* funcName) {
	gstate = PyGILState_Ensure(); //申请获取GIL
	PyObject* pFunc = NULL;

	Py_BEGIN_ALLOW_THREADS;
	Py_BLOCK_THREADS;

	pFunc = PyDict_GetItemString((PyObject*)pDict, funcName);
	if (!pFunc || !PyCallable_Check(pFunc)) {
		return NULL;
	}

	Py_UNBLOCK_THREADS;
	Py_END_ALLOW_THREADS;
	PyGILState_Release(gstate);

	return (void*)pFunc;
}

例子

typedef struct _ModulesParameter_ {
	void* pyModule;
	void* pyDict;
	void* pyFuncRet;
}ModulesParameter;

void* InitGeneratorTfrecord(char* inPythonScrits, char* inTfrecordSavePath){
	ModulesParameter* pModulesParameter = (ModulesParameter*)calloc(1, sizeof(ModulesParameter));
	// 加载tfrecord 模块
	char pyPath[512] = "sys.path.append('./')";
	pModulesParameter->pyModule = LoadPython(inPythonScrits, pyPath);
	if (pModulesParameter->pyModule == NULL) {
		return NULL;
	}

	pModulesParameter->pyDict = GetPDict(pModulesParameter->pyModule);
	if (pModulesParameter->pyDict == NULL) {
		return NULL;
	}
	// 获取tfrecord 模块的初始化函数
	char InitTFrecordFuncName[512] = "InitTFrecord";
	void* pInitTFrecordFunc = GetPFunc(pModulesParameter->pyDict, InitTFrecordFuncName);
	gstate = PyGILState_Ensure(); //申请获取GIL
	Py_BEGIN_ALLOW_THREADS;
	Py_BLOCK_THREADS;

	// 执行tfrecord 初始化函数
	PyObject* pArgs;
	pArgs = PyTuple_New(1);
	PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", inTfrecordSavePath));
	pModulesParameter->pyFuncRet = (void*)PyObject_CallObject((PyObject*)pInitTFrecordFunc, pArgs);

	Py_UNBLOCK_THREADS;
	Py_END_ALLOW_THREADS;
	PyGILState_Release(gstate);

	return (void*)pModulesParameter;
}
void UnitGeneratorTfrecord(void** inTfrecord){
	ModulesParameter* pModulesParameter = (ModulesParameter*)(*inTfrecord);
	// 获取tfrecord 模块的反初始化函数
	char CloseTFrecordFuncName[512] = "CloseTFrecord";
	void* pCloseTFrecordFunc = GetPFunc(pModulesParameter->pyDict, CloseTFrecordFuncName);

	gstate = PyGILState_Ensure(); //申请获取GIL
	Py_BEGIN_ALLOW_THREADS;
	Py_BLOCK_THREADS;

	PyObject* pArgs;
	pArgs = PyTuple_New(1);
	PyTuple_SetItem(pArgs, 0, (PyObject*)pModulesParameter->pyFuncRet);
	PyObject_CallObject((PyObject*)pCloseTFrecordFunc, pArgs);
	/*Py_DECREF(pArgs);*/

	Py_UNBLOCK_THREADS;
	Py_END_ALLOW_THREADS;
	PyGILState_Release(gstate);

	unLoadPyThon(pModulesParameter->pyModule);

	free(*inTfrecord);
	*inTfrecord = NULL;
}
void WriteTfrecord(void* inTfrecord, float* image, int width, int height, int channels, float* reg){
	ModulesParameter* pModulesParameter = (ModulesParameter*)inTfrecord;

	// 获取tfrecord 模块的写入函数
	char WriteTFrecordFuncName[512] = "WriteTFrecord";
	void* pWriteTFrecordFunc = GetPFunc(pModulesParameter->pyDict, WriteTFrecordFuncName);
	float* CArrays = (float*)calloc(width * height * channels, sizeof(float));
	memcpy_s(CArrays, width * height * channels * sizeof(float), image, width * height * channels * sizeof(float));
	npy_intp Dims[3] = { height, width, channels };
	PyObject* PyArray = PyArray_SimpleNewFromData(3, Dims, NPY_FLOAT, (void*)CArrays);

	float* CLabelArray = (float*)calloc(27 * 2, sizeof(float));
	memcpy_s(CLabelArray, 27 * 2 * sizeof(float), reg, 27 * 2 * sizeof(float));
	npy_intp labelDims[2] = { 27, 2 };
	PyObject* PyLabelArray = PyArray_SimpleNewFromData(2, labelDims, NPY_FLOAT, (void*)CLabelArray);

	gstate = PyGILState_Ensure(); //申请获取GIL

	Py_BEGIN_ALLOW_THREADS;
	Py_BLOCK_THREADS;

	PyObject* pArgs;
	pArgs = PyTuple_New(3);
	PyTuple_SetItem(pArgs, 0, (PyObject*)pModulesParameter->pyFuncRet);
	PyTuple_SetItem(pArgs, 1, PyArray);
	PyTuple_SetItem(pArgs, 2, PyLabelArray);

	PyObject_CallObject((PyObject*)pWriteTFrecordFunc, pArgs);
	/*Py_DECREF(pArgs);*/

	Py_UNBLOCK_THREADS;
	Py_END_ALLOW_THREADS;

	PyGILState_Release(gstate);

	if (CArrays) {
		free(CArrays);
		CArrays = NULL;
	}
	if (CLabelArray) {
		free(CLabelArray);
		CLabelArray = NULL;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值