विषय पर बढ़ें

अंतिम अद्यतन:2026-10-12

pybind11 से Python तेज़ करना

आमतौर पर कुछ समय लेने वाले operations के लिए हम चाहते हैं कि वे C++ में implement हों, और फिर Python से संगत interface call हो, या underlying library के कारण, external Python API का समर्थन चाहिए, तो हमें आमतौर पर Python से C++ तक पहुंच का समर्थन चाहिए, इसे कैसे implement करें?

तरीके कई हैं, इस section में pybind11 का उदाहरण लेकर एक पूरा project engineering template प्रस्तावित करते हैं, अगर आपको आगे ऐसी ज़रूरत हो, तो template के आधार पर बदलाव कर सकते हैं।

नोट: (आराम पसंद करने वालों के लिए) इस section का सारा code भी 星球 में रखा गया है।

1. Macro expansion

मान लीजिए: हम समय लेने वाली sorting का उदाहरण लेते हैं, अगर हम C++ में एक sorting लिखकर Python में उसका उपयोग करना चाहें, तो कैसे लिखें?

C++ program काफी सरल है, बाहर एक interface expose करें जिसमें sorting हो, उदाहरण के लिए:

std::vector<int> sort_vector(const std::vector<int>& input) {
  std::vector<int> result = input;
  std::sort(result.begin(), result.end());
  return result;
}

तो प्रश्न यह है, Pybind11 के लिए इस interface का उपयोग कैसे करें?

pybind11 के macro से एक module define किया जा सकता है, उदाहरण के लिए:

PYBIND11_MODULE(sort_module, m) {
    m.doc() = "pybind11 example plugin"; // Optional module docstring

    m.def("sort_vector", &sort_vector, "A function that sorts a list of integers");
}

Macro expand होने के बाद: PyInit_sort_module

जब हम python में import xxx library करते हैं, तो Python interpreter C/C++ में लिखे extension module को load करते समय जो entry function अपने आप call करता है, वही entry function नीचे का PyInit_sort_module है:

static ::pybind11::module_::module_def pybind11_module_def_sort_module [[maybe_unused]];

[[maybe_unused]] static void pybind11_init_sort_module(::pybind11::module_ &);

extern "C" [[maybe_unused]] __attribute__((visibility("default"))) PyObject *PyInit_sort_module();

extern "C" __attribute__((visibility("default"))) PyObject *PyInit_sort_module() {
    {
        const char *compiled_ver = "3" "." "11";
        const char *runtime_ver = Py_GetVersion();
        size_t len = std::strlen(compiled_ver);

        if (std::strncmp(runtime_ver, compiled_ver, len) != 0 || (runtime_ver[len] >= '0' && runtime_ver[len] <= '9')) {
            PyErr_Format(PyExc_ImportError,
                         "Python version mismatch: module was compiled for Python %s, "
                         "but the interpreter version is incompatible: %s.",
                         compiled_ver, runtime_ver);
            return nullptr;
        }
    }

    pybind11::detail::get_internals();
    auto m = ::pybind11::module_::create_extension_module("sort_module", nullptr, &pybind11_module_def_sort_module);

    try {
        pybind11_init_sort_module(m);
        return m.ptr();
    } catch (pybind11::error_already_set & e) {
        pybind11::raise_from(e, PyExc_ImportError, "initialization failed");
        return nullptr;
    } catch (const std::exception &e) {
        ::pybind11::set_error(PyExc_ImportError, e.what());
        return nullptr;
    }
}

void pybind11_init_sort_module(::pybind11::module_ & m) {
    m.doc() = "pybind11 example plugin";

    m.def("sort_vector", &sort_vector, "A function that sorts a list of integers");
}

इसलिए, अगर हम यह macro उपयोग न करें, तो library import करते समय error आएगा:

>>> import sort_module
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define module export function (PyInit_sort_module)

2. CMake + pybind11

pybind11 का C++ में उपयोग इस प्रकार है:

  • Header files
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
  • Macro
PYBIND11_MODULE(sort_module, m) {
    // 你的实现
}

तो cmake में pybind11 को download और link कैसे करें?

बस FetchContent module उपयोग करें, उदाहरण के लिए:

FetchContent_Declare(
    pybind11
    URL https://github.com/pybind/pybind11/archive/v2.12.0.tar.gz
    )

फिर CMakeLists में अपना module जोड़ दें:

pybind11_add_module(sort_module sort_module.cc)

cmake आपके लिए pybingd11 download करके compile भी कर देगा।

3. उपयोग

ऊपर से एक so बनेगा, install करके python के site-packages directory में डालें, फिर import करते समय पहचान लिया जाएगा, नीचे हमारे custom module का demo:

import sort_module

def test_sort():
    input_list = [5, 2, 3, 1, 4]
    sorted_list = sort_module.sort_vector(input_list)
    print(f"Original list: {input_list}")
    print(f"Sorted list: {sorted_list}")

if __name__ == "__main__":
    test_sort()

Run:

(base) ➜  build python ../test.py
Original list: [5, 2, 3, 1, 4]
Sorted list: [1, 2, 3, 4, 5]

संबंधित विषय

टिप्पणियाँ