【Python】调用C++

 
 
 
 

Python 调用 C++ 模块通常有三种方法:

一、直接调用动态库:通过系统原生的 .so(Linux)或 .dll(Windows)文件进行调用。

二、使用 pybind11:借助这一强大的 C++/Python 绑定库,可以便捷地导出 C++ 函数和类。

三、使用 PyTorch Extension:适用于在 PyTorch 框架中集成自定义 C++ 算子。

下面分别展示在 Linux 和 Windows 系统下,使用第一种方法、第二种方法以及 PyTorch Extension 的具体实现示例。

1. Linux下直接调用so:

example.cpp:

// example.cpp
extern "C" {
    int add(int a, int b) {
        return a + b;
    }

    double multiply(double a, double b) {
        return a * b;
    }
}

编译指令:

g++ -shared -fPIC -o libexample.so example.cpp

main.py:

from ctypes import cdll, c_int, c_double

# 加载DLL
lib = cdll.LoadLibrary('./libexample.so')

# 调用函数

lib.add.argtypes = [c_int, c_int]
lib.add.restype = c_int
result = lib.add(3, 4)
print(f"3 + 4 = {result}")

# 对于有明确参数类型的函数,可以指定类型
lib.multiply.argtypes = [c_double, c_double]
lib.multiply.restype = c_double
result = lib.multiply(2.5, 4.0)
print(f"2.5 * 4.0 = {result}")

 

2. Windows下直接调用dll:

example.cpp:

// 使用__declspec(dllexport)导出函数
extern "C" {
    __declspec(dllexport) int add(int a, int b) {
        return a + b;
    }
    
    __declspec(dllexport) double multiply(double a, double b) {
        return a * b;
    }
}

编译指令:

cl /LD example.cpp /link /OUT:example.dll

main.py:

import ctypes
from ctypes import cdll, c_int, c_double

# 加载DLL
lib = cdll.LoadLibrary('./example.dll')

# 调用函数
lib.add.argtypes = [c_int, c_int]
lib.add.restype = c_int
result = lib.add(3, 4)
print(f"3 + 4 = {result}")

# 对于有明确参数类型的函数,可以指定类型
lib.multiply.argtypes = [c_double, c_double]
lib.multiply.restype = c_double
result = lib.multiply(2.5, 4.0)
print(f"2.5 * 4.0 = {result}")

 

3. Linux下使用pybind调用:

example_bind.cpp:

#include <pybind11/pybind11.h>

int add(int a, int b) {
    return a + b;
}

double multiply(double a, double b) {
    return a * b;
}

double divv(double a, double b) {
    return (a / b);
}


// 创建Python模块
PYBIND11_MODULE(example_bind, m) {
    m.def("add", &add, "A function that adds two numbers");
    m.def("multiply", &multiply, "A function that multiplies two numbers");
    m.def("divv", &divv, "A function that div two numbers");

}

编译指令:

g++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example_bind.cpp -o example_bind$(python3-config --extension-suffix)
或:
python setup.py build_ext --inplace

setup.py:

# setup.py
from setuptools import setup, Extension
import pybind11

ext_modules = [
    Extension(
        'example_bind',
        ['example_bind.cpp'],
        include_dirs=[pybind11.get_include()],
        language='c++'
    ),
]

setup(
    name='example_bind',
    ext_modules=ext_modules,
    zip_safe=False,
)

main.py:

import example_bind

result = example_bind.add(3, 4)
print(f"3 + 4 = {result}")

result = example_bind.multiply(2.5, 4.0)
print(f"2.5 * 4.0 = {result}")

result = example_bind.divv(2.5, 4.0)
print(f"2.5 / 4.0 = {result}")

 

4. Windows下使用pybind调用:

example_bind.cpp:

#include <pybind11/pybind11.h>

int add(int a, int b) {
    return a + b;
}

double multiply(double a, double b) {
    return a * b;
}

double divv(double a, double b) {
    return (a / b);
}


// 创建Python模块
PYBIND11_MODULE(example_bind, m) {
    m.def("add", &add, "A function that adds two numbers");
    m.def("multiply", &multiply, "A function that multiplies two numbers");
    m.def("divv", &divv, "A function that div two numbers");

}

编译指令:

cl /EHsc /LD /I C:/Users/xx/AppData/Local/Programs/Python/Python39/include /I C:/Users/xx/AppData/Local/Programs/Python/Python39/Lib/site-packages/pybind11/include example_bind.cpp /link /LIBPATH:C:/Users/xx/AppData/Local/Programs/Python/Python39/libs python39.lib /OUT:example_bind.pyd
或:
python setup.py build_ext --inplace

setup.py:

# setup.py
from setuptools import setup, Extension
import pybind11

ext_modules = [
    Extension(
        'example_bind',
        ['example_bind.cpp'],
        include_dirs=[pybind11.get_include()],
        language='c++'
    ),
]

setup(
    name='example_bind',
    ext_modules=ext_modules,
    zip_safe=False,
)

main.py:

import example_bind

result = example_bind.add(3, 4)
print(f"3 + 4 = {result}")

result = example_bind.multiply(2.5, 4.0)
print(f"2.5 * 4.0 = {result}")

result = example_bind.divv(2.5, 4.0)
print(f"2.5 / 4.0 = {result}")

 

5. 使用 PyTorch Extension 调用:

torch_extension.cpp:

#include <torch/extension.h>

torch::Tensor add_tensors(torch::Tensor a, torch::Tensor b) {
    return a + b;
}

// 注册扩展
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
    m.def("add_tensors", &add_tensors, "Add two tensors");
}

setup.py:

# setup.py
from setuptools import setup
from torch.utils.cpp_extension import CppExtension, BuildExtension

setup(
    name='torch_extension',
    ext_modules=[CppExtension('torch_extension', ['torch_extension.cpp'])],
    cmdclass={'build_ext': BuildExtension}
)

编译指令:

python setup.py install

main.py:

import torch
import torch_extension

a = torch.rand(100)

print(a)
b = torch.rand(100)
result = torch_extension.add_tensors(a, b)
print(result)   
posted @ 2025-10-08 15:38  Dsp Tian  阅读(14)  评论(0)    收藏  举报