前言
最近研究Python调用C++开发的模块,尝试可行的方案有pybind11,cython,boost.python,swig
,下面一一列举用法
环境准备
- MacOS
- Python3
- python模块pybind11/cython
- boost/swig
pip3 install pybind11 cython --user
brew install boost swig
pybind11
编写C++代码
// test.cpp
#include <iostream>
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(testpybind11, m) {
m.doc() = "pybind11 example plugin"; // 导出函数cpp_function
m.def("cpp_function", [](const std::string& s1) {
std::cout << s1 << std::endl;
return s1;
});
}
//
编译兼容模块
c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) -DPYBIND11 test.cpp -o testpybind11$(python3-config --extension-suffix)
# 笔者Mac上生成testpybind11.cpython-39-darwin.so
python测试
import testpybind11
out = testpybind11.cpp_function("hello")
print(out)
cython
编写C++及接口代码
// test.cpp
#define EXPORT __attribute__ ((visibility("default")))
#include <iostream>
EXPORT std::string testcython(const std::string& s1) {
std::cout << s1 << std::endl;
return s1;
}
// testcython.pyx
from libcpp.string cimport string
cdef extern from "test.cpp":
string testcython(const string& s1)
def pytestcython(const string& s1):
return testcython(s1)
编译兼容模块
cython --cplus testcython.pyx -o test_wrapper.cpp
c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) -DPYTHON test_wrapper.cpp -o testcython$(python3-config --extension-suffix)
python测试
import testcython
input_str = "hello"
out = testcython.pytestcython(input_str.encode())
output_str = out.decode()
print(output_str)
boost.python
编写C++代码
// test.cpp
#include <iostream>
#include <boost/python.hpp>
std::string testpyboost(const std::string& s1) {
std::cout << s1 << std::endl;
return s1;
}
BOOST_PYTHON_MODULE(testpyboost)
{
boost::python::def("cpp_function", testpyboost);
}
编译兼容模块
c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) -DPYBOOST test.cpp -o testpyboost$(python3-config --extension-suffix)
python测试
import testpyboost
out = testpyboost.cpp_function("hello")
print(out)
swig
编写C++及接口代码
// test.cpp
#define EXPORT __attribute__ ((visibility("default")))
#include <iostream>
EXPORT std::string pytestswig(const std::string& s1) {
std::cout << s1 << std::endl;
return s1;
}
// test.i
%module testswig
%include "std_string.i"
%{
std::string pytestswig(const std::string& s1);
%}
std::string pytestswig(const std::string& s1);
编译兼容模块
swig -python -c++ test.i
c++ -O3 -Wall -shared -undefined dynamic_lookup $(python3 -m pybind11 --includes) test_wrap.cxx test.cpp -o _testswig$(python3-config --extension-suffix)
python测试
import testswig
out = testswig.pytestswig("hello")
print(out)