设为首页 加入收藏

TOP

关于 C++ 调用 Python 模块的理解
2018-12-19 02:55:15 】 浏览:56
Tags:关于 调用 Python 模块 理解

关于 C++ 调用 Python 模块的理解

这篇博客完美解决了我想在 C++ 中调用 Python 模块的问题,感激不尽!!但是博主写的不够详细,本文在这里对其进行详细说明。

1. 在Python中调用自定义模块

在 C++ 中调用 Python 模块实际上和在 Python 中调用自定义的 Python 模块没哟什么区别,因此,先看看在 Python 中如何调用自定义模块吧!

  • 创建工程:在 PyCharm 中新建一个工程 CallMyModule,然后新建两个目录分别为MainMoudule(主调模块) 和 MyModule(被调模块),在 MainModule 中新建文件test.py, 在 MyModule 中新建文件 module_add.py,如下图所示。
    创建工程
  • 在 module_add.py 中编写简单代码如下:
def add_num(a, b):
    return a+b
  • 在 test.py 中编写代码如下:
import sys
# 将自定义模块的导入路径添加到 sys.path 中
sys.path.append("/Users/jiangpan/BeeLive/Code/Python/CallMyModule/MyModule")
# 可以 print(sys.path) 将 sys.path 打印出来看看添加是否成功
import module_add
print(module_add(1,2))
# 打印出结果 3

2. 在 C++ 中调用自定义的 Python 模块

在 Python 中调用非同一目录下的自定义模块已经成功,那么在C++中来调用自定义的 module_add.py 的主要过程如下:

  • 简要说明:在 C++ 中调用 Python 模块需要要包含头文件 Python.h,由于笔者的开发环境是 Mac+CLion,所以编写 CMakeLists.txt 如下:(Windows+VS 的开发环境可以忽略这一段,Linux 环境下也需要编写 CMakeLists.txt,关于 CMakeLists.txt 本文不做展开)
cmake_minimum_required(VERSION 3.10)
project(page_rotate)
set(CMAKE_CXX_STANDARD 11)
find_package(PythonLibs REQUIRED)
add_executable(page_rotate main.cpp)
target_link_libraries(page_rotate ${PYTHON_LIBRARIES})
  • 在 main.cpp 中调用 module_add.py 模块代码(简单粗暴风格):
#include <iostream>
#include "python3.6m/Python.h"

using namespace std;

int main() {

    Py_Initialize();
    if( Py_IsInitialized() ) {
        PyRun_SimpleString("import sys");
        PyRun_SimpleString("sys.path.append(\"/Users/jiangpan/BeeLive/Code/Python/CallMyModule/MyModule\")");
        PyRun_SimpleString("import module_add");
        PyRun_SimpleString("print(module_add.add_num(1, 2))");
        // 打印出运行结果 3
}
  • 在 main.cpp 中调用 module_add.py 模块代码(装逼风格):
#include <iostream>
#include "python3.6m/Python.h"

using namespace std;

int main() {

    Py_Initialize();
    if( Py_IsInitialized() ) {
        PyRun_SimpleString("import sys");
        // 构造半天字符数组,只为了运行以下这条命令
        // PyRun_SimpleString("sys.path.append(\"/Users/jiangpan/BeeLive/Code/Python/CallMyModule/MyModule\")");
        string path = "/Users/jiangpan/BeeLive/Code/Python/CallMyModule/MyModule";
        string chdir_cmd = string("sys.path.append(\"") + path + "\")";
        const char* cstr_cmd = chdir_cmd.c_str();
        PyRun_SimpleString(cstr_cmd);
        cout << cstr_cmd << endl;   // 把构造了半天的字符数组打印出来看看吧

        // 加载 module_add 模块:PyRun_SimpleString("import module_add");
        PyObject* module_name=NULL;
        PyObject* pModule = NULL;
        pModule = PyImport_ImportModule("module_add");
        if (!pModule) {
            cout << "get Module failed." << endl;
            return -1;
        }
        cout << "get Module succeeded." << endl;

        // 加载函数
        PyObject* pv = PyObject_GetAttrString(pModule, "add_num");
        if (!pv || !PyCallable_Check(pv)) {
            cout << "[ERROR] Can't find funftion (test_add)" << endl;
            return -2;
        }
        cout << "get function (add_num) succeeded." << endl;

        // 设置参数
        PyObject* args = PyTuple_New(2);
        PyObject* arg1 = PyLong_FromLong(4);
        PyObject* arg2 = PyLong_FromLong(3);
        PyTuple_SetItem(args, 0, arg1);
        PyTuple_SetItem(args, 1, arg2);

        // 调用函数
        PyObject* pRet = PyObject_CallObject(pv, args);

        if (!pRet) {
           cout << "function called failed." << endl;
           return -3;
        }
        cout << "function called succeeded." << endl;

        long result = PyLong_AsLong(pRet);
        cout << "result = " << result;
    }
    Py_Finalize();

    return 0;
}

运行结果如下:

自定义Python模块调用结果

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇python2to3的变化 下一篇Python模块的编写和调用

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目