#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;
}
}