近期需要将Python作为模块对项目进行嵌入式开发,但是发现python想要使用C/C++的导出模块必须要用Cython或者是DLL,开发效率并不如LUA脚本开发,所以在此记录下如何利用C/C++调用Python模块。
首先配置环境,在项目中加入Python不同版本自带的include和libs,然后再导入使用的Python版本的DLL文件。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
#include "./../3rd/include/Python.h"
/*
* 初始化Python解释器
*/
static void
init_pythonState() {
Py_Initialize();
}
/*
* 退出Python解释器
*/
static void
exit_pythonState() {
Py_Finalize();
}
/*
* 加载Python模块位置
*/
static void
entry_python_file(const char* module_path) {
char* path = (char*)malloc(sizeof(char) * 100);
memset(path, 0, sizeof(char) * 100);
sprintf(path, "sys.path.append('%s')", module_path);
PyRun_SimpleString("import sys");
PyRun_SimpleString(path);
free(path);
path = NULL;
}
/*
* 使用类保存python模块
*/
class module_tab {
public:
module_tab(PyObject* import_module) : py_module(import_module) {};
public:
PyObject* py_module;
};
module_tab module = NULL;
/*
* 导入python脚本
*/
static bool
import_python_module(const char* module_name) {
PyObject* py_object_module = NULL;
py_object_module = PyImport_ImportModule(module_name);
if (!py_object_module) {
cout << "No such module exists!\n" << endl;
return false;
}
module.py_module = py_object_module;
return true;
}
/*
* 调用python脚本中的函数
*/
static bool
execute_py_function(const char* func_name) {
PyObject* py_object_function = NULL;
py_object_function = PyObject_GetAttrString(module.py_module, func_name);
if (!py_object_function) {
cout << "No such function founded\n" << endl;
return false;
}
PyObject_CallObject(py_object_function, NULL);
return true;
}
/*
* 带参数的函数调用
*/
static bool
execute_py_functionArgs(const char* func_name, PyObject* args) {
PyObject* py_object_function = NULL;
py_object_function = PyObject_GetAttrString(module.py_module, func_name);
if (!py_object_function) {
cout << "No such function founded\n" << endl;
return false;
}
// 返回值是一个PyObject结构,可以转化成不同的C类型
PyObject_CallObject(py_object_function, args);
return true;
}
int main(int argc, char** argv) {
init_pythonState();
entry_python_file("./../../apps");
if (!import_python_module("test2")) {
goto failed;
}
if (!execute_py_function("sayHello")) {
goto failed;
}
PyObject* Args;
Args = Py_BuildValue("is", 11, "Hello?");
if (!execute_py_functionArgs("another", Args)) {
goto failed;
}
printf("Execute success!\n");
failed:
exit_pythonState();
return 0;
}
接下来进行测试
def sayHello() :
print("Hello World?")
def another(number, string) :
if number > 10 :
print(string)
elif number < 10 :
print("argument number smaller than 10\n")
else:
print("argument number equals with 10\n")
可以正常通过Python的解释器进行输出