栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Cmake/Gcc调用 Python模块

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Cmake/Gcc调用 Python模块

文章目录
  • Cmake
  • Gcc
  • Reference

系统:ubuntu 18.04

安装库:

sudo apt-get install python3-dev

其他系统的安装方法
可以通过如下命令检查系统可调用的python

locate Python.h


这里使用最后一个,即 Python3.6

Cmake

CmakeList.txt

cmake_minimum_required(VERSION 3.0.2)
project(c_emb_python)

#set(CMAKE_CXX_STANDARD 14)
set(CMAKE_BUILD_TYPE  Debug)

# 用locate Python.h 取得头文件的位置之后可以使用 #include 
include_directories("/usr/include/python3.6m")

# 下面这个参数通过命令行运行 python3.6-config --ldflags 获得
# -L/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu -L/usr/lib -lpython3.6m -lpthread -ldl  -lutil -lm  -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions

# 添加动态库的位置
LINK_DIRECTORIES("/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu")

add_executable(c_python src/c_python.cpp)
target_link_libraries(c_python -lpython3.6m)

c_python.cpp

//
// Created by daybeha on 2022/7/7.
//

#define PY_SSIZE_T_CLEAN
#include 
#include 

using namespace std;


int main(int argc, char *argv[])
{


    Py_SetProgramName(reinterpret_cast(argv[0]));

//    wchar_t *program = Py_DecodeLocale(argv[0], NULL);
//    if (program == NULL) {
//        fprintf(stderr, "Fatal error: cannot decode argv[0]n");
//        exit(1);
//    }
//    Py_SetProgramName(program);  
//    Py_Initialize();
//    PyRun_SimpleString("from time import time,ctimen"
//                       "print('Today is', ctime(time()))n");
//    if (Py_FinalizeEx() < 0) {
//        exit(120);
//    }
//    PyMem_RawFree(program);
//    return 0;
//


    PyObject *pName, *pModule, *pFunc;
    PyObject *pArgs, *pValue;
    int i;

    if (argc < 3) {
        fprintf(stderr,"Usage: call pythonfile funcname [args]n");
        return 1;
    }

    Py_Initialize();
//    PyRun_SimpleString("#!/usr/include/python3n");
    PyRun_SimpleString("print ('Hello Python!')n");
    PyRun_SimpleString("from time import time,ctimen"
                       "print('Today is', ctime(time()))n");

    PyRun_SimpleString("import platformn"
                       "print(f"Python Version: {platform.python_version()}")n");


    // 将Python工作路径切换到待调用模块所在目录,一定要保证路径名的正确性
    string path = "/home/daybeha/Documents/ROS_proj/test/src/time_acquire/scripts";
    string chdir_cmd = string("sys.path.append("") + path + "")";
//    const char* cstr_cmd = chdir_cmd.c_str();
    PyRun_SimpleString("import sys");
    PyRun_SimpleString(chdir_cmd.c_str());
    PyRun_SimpleString("print(sys.path)");


    // agrv[1] 为 python脚本
    pName = PyUnicode_DecodeFSDefault(argv[1]);


    
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    if (pModule != NULL) {
        // argv[2] 为 指定的函数
        pFunc = PyObject_GetAttrString(pModule, argv[2]);
//        pFunc = PyObject_GetAttrString(pModule, "great_func");

        
        if (pFunc && PyCallable_Check(pFunc)) {
            pArgs = PyTuple_New(argc - 3);
            for (i = 0; i < argc - 3; ++i) {
                pValue = PyLong_FromLong(atoi(argv[i + 3]));
                if (!pValue) {
                    Py_DECREF(pArgs);
                    Py_DECREF(pModule);
                    fprintf(stderr, "Cannot convert argumentn");
                    return 1;
                }
                
                PyTuple_SetItem(pArgs, i, pValue);
            }
            pValue = PyObject_CallObject(pFunc, pArgs);
            Py_DECREF(pArgs);
            if (pValue != NULL) {
                printf("Result of call: %ldn", PyLong_AsLong(pValue));
                Py_DECREF(pValue);
            }
            else {
                Py_DECREF(pFunc);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr,"Call failedn");
                return 1;
            }
        }
        else {
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr, "Cannot find function "%s"n", argv[2]);
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
    }
    else {
        PyErr_Print();
        fprintf(stderr, "Failed to load "%s"n", argv[1]);
        return 1;
    }

    if (Py_FinalizeEx() < 0) {
        return 120;
    }
    return 0;

}

c_py_test.py

def great_func(a):
    return a + 1
    
# # # 查看python 版本
# import platform
# print(platform.python_version())

注:Python文件最好不要命名为test,可能会有冲突

运行

./c_python c_py_test great_func 3

Gcc

如果上面cmake编译不通,可以试试gcc版本:

gcc c_python.cpp -o c_python -I/usr/include/python3.6m -lpython3.6m

执行

./c_python  c_py_test great_func 9

若遇到类似报错:

需要:

export PYTHONPATH=.:/usr/include/python3.6:$PYTHONPATH
Reference

如何实现 C/C++ 与 Python 的通信?
Python.h的Cmake配置
python文档 – 拓展和嵌入
python文档 – python/C API接口
上面文档的中译版
cmake的项目c++调用python方法-爱代码爱编程

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1008304.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号