C++调用python(二)

目录

正文


一、基本使用方法
二、调用简单语句
三、调用函数
四、调用类
五、调用SSD目标检测算法
六、遇到的错误


回到顶部

三、调用函数

3.1 无参

-CMakeLists.txt

cmake_minimum_required(VERSION 3.9)

project(say_hello)

set(SDK_VERSION 0_0_1)
# >>> build type 
set(CMAKE_BUILD_TYPE "Release")# 指定生成的版本
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
# <<<


# >>> CXX11 
set(CMAKE_CXX_STANDARD 11)# C++ 11 编译器
SET(CMAKE_CXX_STANDARD_REQUIRED TRUE)
# <<< 


# >>> Python3 
set(PYTHON_ROOT "/home/zjh/anaconda3/envs/learn")
message("python root: " ${PYTHON_ROOT})
include_directories(${PYTHON_ROOT}/include/)
link_directories(${PYTHON_ROOT}/lib/)
# <<<

# --- generate ---
add_executable(say_hello hello.cpp)
target_link_libraries(say_hello -lpython3.6m)
  • hello.py
def say():
    print("hello")


if __name__ == "__main__":
    say()

  • hello.cpp
#include <python3.6m/Python.h>
#include <iostream>


int main(int argc, char *argv[])
{
    wchar_t *program = Py_DecodeLocale(argv[0], nullptr);
    if ( program == nullptr ){
        std::cout << "Fatal Error: cannot decode argv[0]!" << std::endl;
        return -1;
    }
    Py_SetProgramName(program);
    Py_SetPythonHome((wchar_t*)L"/home/zjh/anaconda3/envs/learn");
    Py_Initialize();
    if ( !Py_IsInitialized() ){
        std::cout << "Python init failed!" << std::endl;
return 0;
    }
    
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('/media/zjh/code/C++_call_python/test/test_hello')");
    
    PyObject* pModule = PyImport_ImportModule("hello");
    if ( pModule == nullptr ){
        std::cout << "module not found!" << std::endl;
        return 1;
    }
    
    PyObject* pFunc = PyObject_GetAttrString(pModule, "say");
    if ( !pFunc || !PyCallable_Check(pFunc) ){
        std::cout << "not found function add_num!" << std::endl;
        return 2;
    }
    PyObject_CallObject(pFunc, nullptr);

    if ( Py_FinalizeEx() < 0 ){
        exit(120);
    }
    PyMem_RawFree(program);
    return 0;
}

3.2 有参

  • CMakeLists.txt
    在3.1的基础上修改开始的program 和最后generate部分就行。

  • add.py

def add_num(a, b):
    print("the result {} + {} is {}".format(a, b, a+b))
    return a + b


if __name__ == "__main__":
    add_num(1, 2)

  • add.cpp
#include <python3.6m/Python.h>
#include <iostream>


int main(int argc, char *argv[])
{
    wchar_t *program = Py_DecodeLocale(argv[0], nullptr);
    if ( program == nullptr ){
        std::cout << "Fatal Error: cannot decode argv[0]!" << std::endl;
        return -1;
    }
    Py_SetProgramName(program);
    Py_Initialize();
    if ( !Py_IsInitialized() ){
        std::cout << "Python init failed!" << std::endl;
return 0;
    }
    
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('/home/work/C++_python/test/test_add')");
    
    PyObject* pModule = PyImport_ImportModule("add");
    if ( pModule == nullptr ){
        std::cout << "module not found!" << std::endl;
        return 1;
    }
    
    PyObject* pFunc = PyObject_GetAttrString(pModule, "add_num");
    if ( !pFunc || !PyCallable_Check(pFunc) ){
        std::cout << "not found function add_num!" << std::endl;
        return 2;
    }
    
    PyObject* args = Py_BuildValue("(ii)", 28, 103);
    PyObject* pRet = PyObject_CallObject(pFunc, args);
    Py_DECREF(args);
     
    int res = 0;
    PyArg_Parse(pRet, "i", &res);
    Py_DECREF(pRet);
    std::cout << "the res is: " << res << std::endl;

    if ( Py_FinalizeEx() < 0 ){
        exit(120);
    }
    PyMem_RawFree(program);
    return 0;
}

回到顶部

四、调用类

  • CMakeLists.txt

  • test_class.py

class Test(object):
    def __init__(self):
        self.i = 1
        print("init!")

    def modify(self):
        self.i += 1

    def do(self):
        print(self.i)
 
if __name__ == "__main__":
    test_class = Test()
    test_class.do()
    test_class.modify()
    test_class.do()

  • testClass.cpp
#include <python3.6m/Python.h>
#include <iostream>


int main(int argc, char *argv[])
{
    wchar_t *program = Py_DecodeLocale(argv[0], nullptr);
    if ( program == nullptr ){
        std::cout << "Fatal Error: cannot decode argv[0]!" << std::endl;
        return -1;
    }
    Py_SetProgramName(program);
    Py_Initialize();
    if ( !Py_IsInitialized() ){
        std::cout << "Python init failed!" << std::endl;
return 0;
    }
    
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('/home/work/C++_python/test/test_class')");
    
    // 1. 导入模块
    PyObject* pModule = PyImport_ImportModule("test_class");
    if ( pModule == nullptr ){
        std::cout << "module not found!" << std::endl;
        return 1;
    }

    PyObject* pTestDict = PyModule_GetDict(pModule);
    
    
    // 2. 导入模块中方法或类
    PyObject* pTestClass = PyDict_GetItemString(pTestDict, "Test");

    // 3. 创建实例
    PyObject* pTestInstance = nullptr;
    if ( PyCallable_Check(pTestClass) ){
        pTestInstance = PyObject_CallObject(pTestClass, nullptr);
    }
    
    // 4. 调用类方法
    PyObject_CallMethod(pTestInstance, "do", nullptr);
    PyObject_CallMethod(pTestInstance, "modify", nullptr);
    PyObject_CallMethod(pTestInstance, "do", nullptr);

    if ( Py_FinalizeEx() < 0 ){
        exit(120);
    }
    PyMem_RawFree(program);
    return 0;
}

注:如果类函数有参数,可以参照4.2中方法

posted @ 2022-09-29 21:49  MasonLee  阅读(52)  评论(0编辑  收藏  举报