서문
파이썬의 장점은 높은 개발 효율성과 사용 용이성인 반면, C++의 장점은 운영 효율성이 높다는 것은 누구나 아는 사실입니다. Python에서 프로젝트에 C++ 코드를 포함하거나 Python을 사용하여 C++ 프로젝트에서 주변 기능을 구현하는 경우 Python에서 C++ 모듈을 호출해야 할 수 있습니다. 다음은 C++ 코드를 Python 인터페이스로 내보내는 몇 가지 기본 방법입니다. 함께. .
원래 내보내기
Python 인터프리터는 C로 구현되므로 C++ 데이터 구조를 Python에서 이해할 수 있습니다. , 이론적으로는 직접 호출할 수 있습니다. test1.cpp를 다음과 같이 구현합니다
#include <Python.h> int Add(int x, int y) { return x + y; } int Del(int x, int y) { return x - y; } PyObject* WrappAdd(PyObject* self, PyObject* args) { int x, y; if (!PyArg_ParseTuple(args, "ii", &x, &y)) { return NULL; } return Py_BuildValue("i", Add(x, y)); } PyObject* WrappDel(PyObject* self, PyObject* args) { int x, y; if (!PyArg_ParseTuple(args, "ii", &x, &y)) { return NULL; } return Py_BuildValue("i", Del(x, y)); } static PyMethodDef test_methods[] = { {"Add", WrappAdd, METH_VARARGS, "something"}, {"Del", WrappDel, METH_VARARGS, "something"}, {NULL, NULL} }; extern "C" void inittest1() { Py_InitModule("test1", test_methods); }
컴파일 명령은 다음과 같습니다
g++ -fPIC -shared test1.cpp -I/usr/include/python2.6 -o test1.so
파이썬 해석 실행 테스트는 다음과 같습니다
>>> import test1 >>> test1.Add(1,2) 3
여기서 몇 가지 주의할 점이 있습니다
생성된 동적 라이브러리의 이름이 test1이면 소스 파일에 inittest1 함수가 있어야 하며 Py_InitModule의 첫 번째 매개변수는 "test1"이어야 합니다. 그렇지 않으면 Python에서 모듈을 가져오는 데 실패합니다.
cpp 소스 파일인 경우 inittest1 함수를 extern "C"로 수정해야 합니다. c 소스 파일인 경우에는 필요하지 않습니다. 그 이유는 Python 인터프리터가 라이브러리를 가져올 때 initxxx와 같은 함수를 찾고, C와 C++는 함수 기호를 다르게 인코딩하기 때문입니다. 특히 C++에서는 함수 기호를 인코딩할 때 함수 길이와 매개변수 유형을 고려합니다. 함수 기호는 부스트nm test1.so
를 통해 함수 프로토타입을 디코딩할 수 있습니다.
#include <boost/python/module.hpp> #include <boost/python/def.hpp> using namespace boost::python; int Add(const int x, const int y) { return x + y; } int Del(const int x, const int y) { return x - y; } BOOST_PYTHON_MODULE(test2) { def("Add", Add); def("Del", Del); }
g++ test2.cpp -fPIC -shared -o test2.so -I/usr/include/python2.6 -I/usr/local/include -L/usr/local/lib -lboost_python
참고: Path를 컴파일할 때 부스트 헤더 파일과 라이브러리를 지정하십시오. 여기에는 /usr/local/include 및 /usr/local/lib
가 있거나 setup.py#!/usr/bin/env python from distutils.core import setup from distutils.extension import Extension setup(name="PackageName", ext_modules=[ Extension("test2", ["test2.cpp"], libraries = ["boost_python"]) ])
python setup.py build
>>> import test2 >>> test2.Add(1,2) 3 >>> test2.Del(1,2) -1
#include <boost/python.hpp> using namespace boost::python; class Test { public: int Add(const int x, const int y) { return x + y; } int Del(const int x, const int y) { return x - y; } }; BOOST_PYTHON_MODULE(test3) { class_<Test>("Test") .def("Add", &Test::Add) .def("Del", &Test::Del); }
참고: BOOST_PYTHON_MODULE에서 .def를 사용하는 것은 Python 구문과 다소 유사합니다. 이는
class_<Test>("Test").def("Add", &Test::Add); class_<Test>("Test").def("Del", &Test::Del);
g++ test3.cpp -fPIC -shared -o test3.so -I/usr/include/python2.6 -I/usr/local/include/boost -L/usr/local/lib -lboost_python
>>> import test3 >>> test = test3.Test() >>> test.Add(1,2) 3 >>> test.Del(1,2) -1
가변 매개변수 내보내기 함수
#include <boost/python.hpp> using namespace boost::python; class Test { public: int Add(const int x, const int y, const int z = 100) { return x + y + z; } }; int Del(const int x, const int y, const int z = 100) { return x - y - z; } BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Add_member_overloads, Add, 2, 3) BOOST_PYTHON_FUNCTION_OVERLOADS(Del_overloads, Del, 2, 3) BOOST_PYTHON_MODULE(test4) { class_<Test>("Test") .def("Add", &Test::Add, Add_member_overloads(args("x", "y", "z"), "something")); def("Del", Del, Del_overloads(args("x", "y", "z"), "something")); }
g++ test4.cpp -fPIC -shared -o test4.so -I/usr/include/python2.6 -I/usr/local/include/boost -L/usr/local/lib -lboost_python
>>> import test4 >>> test = test4.Test() >>> print test.Add(1,2) 103 >>> print test.Add(1,2,z=3) 6 >>> print test4.Del(1,2) -1 >>> print test4.Del(1,2,z=3) -1
Python 객체로 인터페이스 내보내기
def Square(list_a) { return [x * x for x in list_a] }
#include <boost/python.hpp> boost::python::list Square(boost::python::list& data) { boost::python::list ret; for (int i = 0; i < len(data); ++i) { ret.append(data[i] * data[i]); } return ret; } BOOST_PYTHON_MODULE(test5) { def("Square", Square); }
g++ test5.cpp -fPIC -shared -o test5.so -I/usr/include/python2.6 -I/usr/local/include/boost -L/usr/local/lib -lboost_python
>>> import test5 >>> test5.Square([1,2,3]) [1, 4, 9]
, boost::python::tuple
, boost::python::list
이러한 데이터 유형의 사용 방법은 기본적으로 Python과 일치합니다. 특정 방법의 경우 Boost 헤더 파일 boost::python::dict
이고, 사용방법은 다음과 같습니다. boost::python::make_tuple()
boost::python::tuple(int a, int b, int c) { return boost::python::make_tuple(a, b, c); }