有些操作使用python来完成会更方便,比如执行一些网络请求、爬虫等操作。
环境声明
Visual Studio C++14
Python313
要把python文件和cpp文件放在同一目录下。
Python
新建一个名为pyif.py(可自定义)的文件,并写入以下测试函数,由C++代码输入名字参数,然后由python构造一个字典列表并返回。
def test_cpp_intf(name):
dict_list =[]
dict = {
'name': name
}
dict_list .append(name_dict)
return dict_list
C++
环境配置
1. 在Visual Studio项目属性页-Release-VC++目录-包含目录添加python的include路径
C:\Program Files\Python313\include
2. 在Visual Studio项目属性页-Release-VC++目录-库目录添加python的libs路径
C:\Program Files\Python313\libs
源代码
// 其它包含头文件
#include <Python.h>
void CallPyFunc() {
PyObject* pModule = nullptr;
PyObject* pFunc = nullptr;
PyObject* pArgs = nullptr;
PyObject* pName = nullptr;
PyObject* pResult = nullptr;
const wchar_t* inputName = L"帅哥";
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('.')");
pModule = PyImport_ImportModule("pyif");// python file name
if (pModule == nullptr) {
std::cout << "Can not import module" << std::endl;
goto Cleanup;
}
pFunc = PyObject_GetAttrString(pModule, "test_cpp_intf");// python function name
if (pFunc == nullptr || PyCallable_Check(pFunc) == false) {
std::cout << "Can not find the function or function is not callable" << std::endl;
goto Cleanup;
}
// Prepare the input param
pArgs = PyTuple_New(1);// new an empty tuple
if (pArgs == nullptr) {
std::cout << "PyTuple_New failed" << std::endl;
goto Cleanup;
}
pName = PyUnicode_FromWideChar(inputName, -1);
if (pName == nullptr) {
std::cout << "PyUnicode_FromWideChar failed" << std::endl;
goto Cleanup;
}
// Inser pName to the tuple. Tuple steals reference, so do not Py_DECREF(Decrease Reference)
PyTuple_SetItem(pArgs, 0, pName);
pResult = PyObject_CallObject(pFunc, pArgs);// 调用函数,返回一个字典列表
if (pResult == nullptr || PyList_Check(pResult) == false) {// 检查是不是列表
std::cout << "PyObject_CallObject failed or result is not a list" << std::endl;
goto Cleanup;
}
for (Py_ssize_t i = 0; i < PyList_Size(pResult); i++) {
PyObject* dict= PyList_GetItem(pResult, i);
if (PyDict_Check(dict) == false) {// 检查是不是字典
continue;
}
// 解析字典
std::string name = ParsePyDictValueByKey(dict, "name");
std::cout << name<< std::endl;
}
Cleanup:
if (pResult) Py_DECREF(pResult);
if (pArgs) Py_DECREF(pArgs);
if (pFunc) Py_DECREF(pFunc);
if (pModule) Py_DECREF(pModule);
Py_Finalize();
}
std::string ParsePyDictValueByKey(PyObject* dict, const char* key) {
PyObject* pValue = PyDict_GetItemString(dict, key);
if (pValue) {
if (PyUnicode_Check(pValue)) {
PyObject* temp_bytes = PyUnicode_AsEncodedString(pValue, "ANSI", "strict");
if (temp_bytes != NULL) {
std::string result = PyBytes_AS_STRING(temp_bytes);
Py_DECREF(temp_bytes);
return result;
}
}
else if (PyLong_Check(pValue)) {
long value = PyLong_AsLong(pValue);
return std::to_string(value);
}
else if (PyFloat_Check(pValue)) {
double value = PyFloat_AsDouble(pValue);
return std::to_string(static_cast<int>(value));
}
}
return "";
}
C++调用Python函数方法详解
1154

被折叠的 条评论
为什么被折叠?



