使用c++扩展python


简介c++可以编写python的扩展库。1.Extending Python with C or C++ — Python 3.11.4 documentation开发环境linux 下需要安装python3-devCMAKE编写这里给出test.cpp编写的python模块和测试用 的test.py编译与执行1mkdir build23cmake -S . -B ./build45cmake --build ./build67python3 test.py1cmake_minimum_required(VERSION 3.12) # 3.12才可以find_package(python)2project(test_cp)34find_package (Python REQUIRED Interpreter Development)56set(test_cpp_demo_name "test_cpp") # 定义一个库的名字,同时作为py模块的名7add_definitions(-DPY_MODULE_NAME_STR="${test_cpp_demo_name}")8add_definitions(-DPY_MODULE_NAME=PyInit_${test_cpp_demo_name})91011add_library(${test_cpp_demo_name} SHARED test.cpp)12set_target_properties(13 ${test_cpp_demo_name}14 PROPERTIES15 PREFIX "" # 输出前缀没有了16 OUTPUT_NAME ${test_cpp_demo_name}.cpython-310-x86_64-linux-gnu # 注意后边的python版本、平台版本、编译器组织17)18target_include_directories(${test_cpp_demo_name} PRIVATE19 ${Python_INCLUDE_DIRS})2021target_link_directories(${test_cpp_demo_name} PRIVATE22 ${Python_LIBRARY_DIRS})2324target_link_libraries(${test_cpp_demo_name} PRIVATE25 ${Python_LIBRARIES})TEST.CPP具体可以参考上边给出的链接1#include "Python.h"23// 起一个命名空间4namespace test_cpp {5constexpr int N = 1000;6int f[N];7bool flag = false;8int Fib_impl(int n) {9 if (flag && 0 <= n && n < N) {10 return f[n];11 }12 f[1] = 1;13 for (int i = 2; i < N; ++i) {14 f[i] = f[i - 1] + f[i - 2];15 }16 flag = true;17 return f[n];18}19} // namespace test_cpp2021// python导出接口22static PyObject *Fib(PyObject * /* unused module reference */,PyObject *o) {23 int n = PyLong_AsLong(o);24 int fn = test_cpp::Fib_impl(n);25 return Py_BuildValue("i", fn);26}2728//定义python模块中有哪些函数29static struct PyMethodDef test_cpp_methods[] = {30 {"fast_fib", Fib, METH_O, "fast fib"},31 // Terminate the array with an object containing nulls.32 {nullptr, nullptr, 0, nullptr}};3334// 定义模块35static struct PyModuleDef test_cpp_module = {36 PyModuleDef_HEAD_INIT,37 PY_MODULE_NAME_STR, /* name of module */ // python里可以import这个名字38 nullptr, /* module documentation, may be NULL */39 -1, /* size of per-interpreter state of the module,40 or -1 if the module keeps state in globalvariables. */41 test_cpp_methods42 };43//定义模块的初始化函数,import之后会自动执行444546// .so的名字要和这个函数的名字、和PyModuleDef里的name对齐47PyMODINIT_FUNC PY_MODULE_NAME(void) {48 PyObject *m;49 m = PyModule_Create(&test_cpp_module);50 if (m == NULL)51 return NULL;52 return m;53}PYTHON使用1import sys2# sys.path.append("./build/lib.linux-x86_64-3.10")3sys.path.append("./build")4import test_cpp56a = test_cpp.fast_fib(10);7print(a)