Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Cách sử dụng đối tượng Python trong C++ (Embedding Python)

Để dùng đối tượng Python trong C++, nhúng (embed) Python interpreter vào ứng dụng C++. Cách phổ biến: dùng Python C API hoặc tool như pybind11 (khuyên dùng hiện đại), Cython.

Ví dụ dùng Cython (như bài gốc)

File pycls.pyx – định nghĩa class Python và wrapper public:

class PyClass(object):
    def __init__(self):
        self.data = []
    def add(self, val):
        self.data.append(val)
    def __str__(self):
        return "Data: " + str(self.data)

cdef public object createPyClass():
    return PyClass()

cdef public void addData(object p, int val):
    p.add(val)

cdef public char* printCls(object p):
    return bytes(str(p), encoding='utf-8')

Biên dịch: cython --cplus pycls.pyx → sinh pycls.cpp và pycls.h.

File main.cpp – nhúng Python và gọi:

#include <Python.h>
#include "pycls.h"

int main(int argc, char* argv[]) {
    Py_Initialize();           // Khởi tạo Python interpreter
    PyInit_pycls();            // Khởi tạo module (initpycls() trong Python 2)
    
    PyObject* obj = createPyClass();
    for (int i = 0; i < 10; ++i) {
        addData(obj, i);
    }
    printf("%s\n", printCls(obj));
    
    Py_Finalize();             // Dọn dẹp
    return 0;
}

Biên dịch & link:

g++ pycls.cpp main.cpp -o app $(python3-config --cflags --ldflags) -std=c++17

Chạy: ./app → Data: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Cách hiện đại khuyên dùng: pybind11

pybind11 – Header-only library, dễ dùng, hiệu năng tốt, hỗ trợ C++11+.

// example.cpp
#include <pybind11/embed>  // Embed Python
#include <pybind11/pybind11.h>
#include <iostream>

namespace py = pybind11;

int main() {
    py::scoped_interpreter guard{};  // Khởi tạo & tự dọn dẹp (RAII)
    
    py::object pyClass = py::module::import("my_module").attr("PyClass");
    py::object obj = pyClass();      // Tạo instance
    for (int i = 0; i < 10; ++i) {
        obj.attr("add")(i);          // Gọi method
    }
    std::cout << py::str(obj.attr("__str__")()) << std::endl;
    return 0;
}

CMake: find_package(pybind11 REQUIRED) → target_link_libraries(app PRIVATE pybind11::embed).

So sánh

Cách Ưu điểm Nhược điểm
Python C API (raw) Không dependency, kiểm soát tối đa Verbose, dễ leak refcount, error-prone
Cython Tốc độ C, dễ viết extension module Cần build step riêng, syntax hybrid
pybind11 (khuyên dùng) Header-only, C++11 idiomatic, RAII, hỗ trợ STL↔Python container auto-convert Cần C++11+, binary size lớn hơn chút
Boost.Python Mature, strong Heavy dependency, compile chậm