C++에서 Python 코드 사용하기 (Boost.Python 사용)
14499 단어 boost.pythonPythonC++
추기: 함부로 쓰지 않도록 주의해라!
만약 C++로 번거로운 처리를 포기하고 파이톤으로 '가볍다' 를 쓴다면, 절대로 이 글을 쓰지 마세요.
환경 간 파이토존과 포장의 설치 상황 문제 등으로 인해 유지보수를 위해 앞으로 고통스러울 것으로 보인다.
이 글의 방법은 목적 라이브러리가 파이톤에서만 사용할 수 있다면 어떻게든 필요할 때의 최종 수단으로 추천하는 것이다.
기본적으로 C++용 프로그램 라이브러리를 사용해서 C++부터 std::system("python3 xxx.py")
파이톤 명령을 두드리거나 파이톤으로만 코드를 완성하는 것을 권장합니다.
(예를 들어 OpenCV와 Pytric는 C++에서 직접 처리할 수 있고 매트릭스 계산은nupy 대신 C++로 매트릭스 라이브러리에 있는 Eigen을 사용할 수 있다.)
개시하다
Boost.파이톤은 주로 C++를 사용하여 파이톤용 프로그램 라이브러리를 만드는 데 사용되고, 반대로 파이톤의 코드는 C++ 옆에 있는 이른바 '끼워넣기' (Embeding) 에도 사용된다.
C++에서 파이톤을 사용하는 코드에 대한 수요가 많지 않아'boost pythhon'등에서 검색해도 상반된 용도(Pythn에서 C++로 코드를 사용하는 경우)에 대한 글만 나온다.
이 경우, 'embed' (끼워넣기) 라는 검색 키워드가 포함되면, C++에 파이톤이 끼워진 글을 쉽게 찾을 수 있습니다.
가장 간단한 코드 예시
main.cpp#include <boost/python.hpp>
namespace py = boost::python;
int main()
{
Py_Initialize(); // 最初に呼んでおく必要あり
try
{
// Pythonで「print('Hello World!')」を実行
py::object global = py::import("__main__").attr("__dict__");
py::exec("print('Hello World!')", global);
}
catch (const py::error_already_set &)
{
// Pythonコードの実行中にエラーが発生した場合はエラー内容を表示
PyErr_Print();
}
return 0;
}
이 견본은 py::exec()
함수를 사용하여 파이톤 코드 print('Hello World!')
를 간단하게 실행합니다.
변수global
에 파이톤의 전역 이름 공간 대상을 가져오면 코드가 파이톤의 전역 이름 공간에서 실행됩니다.
Boost.파이톤은 뒤에서 파이톤의 C 인터페이스를 부르기 때문에 사용하기 전에 Py_Initialize()
함수를 먼저 불러야 한다.
(※ 또한 공식 튜토리얼Py_Finalize()
에 따라 코드 내에서 호칭할 수 없음)
또한 파이썬이 실행될 때 오류가 발생했을 때py::error_already_set
는 형식 예외를 보내기 때문에catch 후PyErr_Print()
에 내용이 표시됩니다.
컴파일 방법(Linux+GCC 시)
Linux+GCC에서는 다음 명령을 사용하여 컴파일할 수 있습니다.
편역 방법$ g++ main.cpp `pkg-config python3-embed --cflags --libs` -lboost_python38
환경에 따라 python3-embed
의 버전이 없을 수 있습니다. 적절히 pkg-config python3
python3-embed
의 버전으로 변경해 주십시오. 원래 버전에서 끼워 넣는 프로그램 라이브러리를 제외하고 pkg-config python3
를 사용하면 링크 오류가 발생할 수 있습니다).
또한 상기boost_python38
의 부분은 버전과 환경에 따라 boost_python-py38
의 형식이 다르다.
링크해야 하는 Boost입니다.파이톤의 라이브러리 이름을 모르면 다음 명령을 통해 조사할 수 있습니다.
나온 lib**.so
의 **
부분은 창고 이름이다.
Boost.파이썬의 라이브러리 이름을 모를 때 조사하는 방법$ ldconfig -p | grep "boost_python3"
기본용법
다음은 각 구체적인 함수의 사용 방법을 살펴보자.
이후에는 namespace py = boost::python;
라고 쓰여 있다고 가정하고 py
로 표시한다.
코드의 global
는 첫 번째 샘플과 마찬가지로 다음 코드를 통해 얻은 전역 이름 공간 대상입니다.py::object global = py::import("__main__").attr("__dict__");
■py:eval (): 파이톤으로 공식을 평가하고 결과를 되돌려줍니다
파이톤의 표현식을 문자열로 제시하면 결과는 py::object
형식으로 되돌아옵니다.
아래와 같이 py::extract<型名>
조합은 C++ 형식으로 결과를 얻을 수 있다.// "2**3"の結果を取得
py::object result = py::eval("2**3", global);
// 結果をint型に変換して出力
std::cout << py::extract<int>(result) << std::endl;
실행 결과8
이 예에서는 파이썬 내 함수 등을 특별히 사용하지 않아 두 번째 매개변수의 네임스페이스global
를 생략해도 이동할 수 있습니다.
그러나 두 번째 인자를 생략하면 pow
등 파이톤이 함수에 삽입되고 다른 사용자가 정의한 변수, 함수를 사용할 수 없음을 주의하십시오.
■py:exec(): 문자열을 통한 파이썬 코드 실행 전달
첫 번째 견본과 같이 py::exec()
함수는 문자열에 파이톤 코드를 제공한 후 바로 실행됩니다.py::eval()
와 달리 여러 명령을 실행하거나 분류를 구분할 수 있습니다.py::exec(
"print('Hello!')\n"
"print('World!')", global);
실행 결과Hello!
World!
변수를 새로 만들면 두 번째 매개변수의 네임스페이스에 생성됩니다.// Pythonのグローバル名前空間内のresult変数に2**3を代入
py::exec("result = 2**3", global);
// 結果をint型に変換して出力
std::cout << py::extract<int>(global["result"]) << std::endl;
실행 결과8
■ py::exec_파일에서 Python 코드 실행하기
py::exec_file()
를 사용하면 파일 내용을 읽을 수 있으며 py::exec()
와 같이 실행할 수 있습니다.
첫 번째 매개 변수는 Pythhon 스크립트의 파일 경로를 지정합니다.py::exec_file("hello.py", global);
사용자 정의 클래스의 정의를 C++와 분리해서 Python 스크립트 파일로 준비하면 편리합니다.
■py:object::attra():참조 객체의 필드/방법
py::object
의 필드(구성원 변수)나 방법(구성원 함수)은 attr()
함수를 사용할 수 있습니다.
str형join 방법을 호출하는 예// ['hoge','fuga','piyo']というリストを作成
py::object list = py::eval("['hoge','fuga','piyo']", global);
// 「','.join(list)」を実行し、リストの文字列をカンマ区切りで結合
py::object result = py::object(",").attr("join")(list);
// 結果を文字列型に変換して出力
std::string resultStr = py::extract<std::string>(result);
std::cout << resultStr << std::endl;
실행 결과hoge,fuga,piyo
■py:import():Python 라이브러리 사용
py::import
를 사용하면 파이톤의 import
문장과 같이 라이브러리를 가져올 수 있습니다.py::object np = py::import("numpy");
예를 들어 다음 Python 코드py::exec()
는 사용하지 않고 C++로 써 보세요.
matplotlib에 y=x^2 도표의 견본을 표시합니다.
코드 샘플import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-10, 10, 0.1)
y = x ** 2
plt.plot(x, y)
plt.show()
지금까지 Boost였습니다.파이썬을 사용하여 C++로 작성한 샘플py::object np = py::import("numpy");
py::object plt = py::import("matplotlib.pyplot");
py::object x = np.attr("arange")(-10, 10, 0.1);
py::object y = x * x;
plt.attr("plot")(x, y);
plt.attr("show")();
(C++측은 직접 쓸 수 없기 때문에x ** 2
x * x
로 대체)
실행하면 다음 matplotlib을 통해 도표를 표시합니다.
참고 자료
Boost.파이톤은 주로 C++를 사용하여 파이톤용 프로그램 라이브러리를 만드는 데 사용되고, 반대로 파이톤의 코드는 C++ 옆에 있는 이른바 '끼워넣기' (Embeding) 에도 사용된다.
C++에서 파이톤을 사용하는 코드에 대한 수요가 많지 않아'boost pythhon'등에서 검색해도 상반된 용도(Pythn에서 C++로 코드를 사용하는 경우)에 대한 글만 나온다.
이 경우, 'embed' (끼워넣기) 라는 검색 키워드가 포함되면, C++에 파이톤이 끼워진 글을 쉽게 찾을 수 있습니다.
가장 간단한 코드 예시
main.cpp#include <boost/python.hpp>
namespace py = boost::python;
int main()
{
Py_Initialize(); // 最初に呼んでおく必要あり
try
{
// Pythonで「print('Hello World!')」を実行
py::object global = py::import("__main__").attr("__dict__");
py::exec("print('Hello World!')", global);
}
catch (const py::error_already_set &)
{
// Pythonコードの実行中にエラーが発生した場合はエラー内容を表示
PyErr_Print();
}
return 0;
}
이 견본은 py::exec()
함수를 사용하여 파이톤 코드 print('Hello World!')
를 간단하게 실행합니다.
변수global
에 파이톤의 전역 이름 공간 대상을 가져오면 코드가 파이톤의 전역 이름 공간에서 실행됩니다.
Boost.파이톤은 뒤에서 파이톤의 C 인터페이스를 부르기 때문에 사용하기 전에 Py_Initialize()
함수를 먼저 불러야 한다.
(※ 또한 공식 튜토리얼Py_Finalize()
에 따라 코드 내에서 호칭할 수 없음)
또한 파이썬이 실행될 때 오류가 발생했을 때py::error_already_set
는 형식 예외를 보내기 때문에catch 후PyErr_Print()
에 내용이 표시됩니다.
컴파일 방법(Linux+GCC 시)
Linux+GCC에서는 다음 명령을 사용하여 컴파일할 수 있습니다.
편역 방법$ g++ main.cpp `pkg-config python3-embed --cflags --libs` -lboost_python38
환경에 따라 python3-embed
의 버전이 없을 수 있습니다. 적절히 pkg-config python3
python3-embed
의 버전으로 변경해 주십시오. 원래 버전에서 끼워 넣는 프로그램 라이브러리를 제외하고 pkg-config python3
를 사용하면 링크 오류가 발생할 수 있습니다).
또한 상기boost_python38
의 부분은 버전과 환경에 따라 boost_python-py38
의 형식이 다르다.
링크해야 하는 Boost입니다.파이톤의 라이브러리 이름을 모르면 다음 명령을 통해 조사할 수 있습니다.
나온 lib**.so
의 **
부분은 창고 이름이다.
Boost.파이썬의 라이브러리 이름을 모를 때 조사하는 방법$ ldconfig -p | grep "boost_python3"
기본용법
다음은 각 구체적인 함수의 사용 방법을 살펴보자.
이후에는 namespace py = boost::python;
라고 쓰여 있다고 가정하고 py
로 표시한다.
코드의 global
는 첫 번째 샘플과 마찬가지로 다음 코드를 통해 얻은 전역 이름 공간 대상입니다.py::object global = py::import("__main__").attr("__dict__");
■py:eval (): 파이톤으로 공식을 평가하고 결과를 되돌려줍니다
파이톤의 표현식을 문자열로 제시하면 결과는 py::object
형식으로 되돌아옵니다.
아래와 같이 py::extract<型名>
조합은 C++ 형식으로 결과를 얻을 수 있다.// "2**3"の結果を取得
py::object result = py::eval("2**3", global);
// 結果をint型に変換して出力
std::cout << py::extract<int>(result) << std::endl;
실행 결과8
이 예에서는 파이썬 내 함수 등을 특별히 사용하지 않아 두 번째 매개변수의 네임스페이스global
를 생략해도 이동할 수 있습니다.
그러나 두 번째 인자를 생략하면 pow
등 파이톤이 함수에 삽입되고 다른 사용자가 정의한 변수, 함수를 사용할 수 없음을 주의하십시오.
■py:exec(): 문자열을 통한 파이썬 코드 실행 전달
첫 번째 견본과 같이 py::exec()
함수는 문자열에 파이톤 코드를 제공한 후 바로 실행됩니다.py::eval()
와 달리 여러 명령을 실행하거나 분류를 구분할 수 있습니다.py::exec(
"print('Hello!')\n"
"print('World!')", global);
실행 결과Hello!
World!
변수를 새로 만들면 두 번째 매개변수의 네임스페이스에 생성됩니다.// Pythonのグローバル名前空間内のresult変数に2**3を代入
py::exec("result = 2**3", global);
// 結果をint型に変換して出力
std::cout << py::extract<int>(global["result"]) << std::endl;
실행 결과8
■ py::exec_파일에서 Python 코드 실행하기
py::exec_file()
를 사용하면 파일 내용을 읽을 수 있으며 py::exec()
와 같이 실행할 수 있습니다.
첫 번째 매개 변수는 Pythhon 스크립트의 파일 경로를 지정합니다.py::exec_file("hello.py", global);
사용자 정의 클래스의 정의를 C++와 분리해서 Python 스크립트 파일로 준비하면 편리합니다.
■py:object::attra():참조 객체의 필드/방법
py::object
의 필드(구성원 변수)나 방법(구성원 함수)은 attr()
함수를 사용할 수 있습니다.
str형join 방법을 호출하는 예// ['hoge','fuga','piyo']というリストを作成
py::object list = py::eval("['hoge','fuga','piyo']", global);
// 「','.join(list)」を実行し、リストの文字列をカンマ区切りで結合
py::object result = py::object(",").attr("join")(list);
// 結果を文字列型に変換して出力
std::string resultStr = py::extract<std::string>(result);
std::cout << resultStr << std::endl;
실행 결과hoge,fuga,piyo
■py:import():Python 라이브러리 사용
py::import
를 사용하면 파이톤의 import
문장과 같이 라이브러리를 가져올 수 있습니다.py::object np = py::import("numpy");
예를 들어 다음 Python 코드py::exec()
는 사용하지 않고 C++로 써 보세요.
matplotlib에 y=x^2 도표의 견본을 표시합니다.
코드 샘플import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-10, 10, 0.1)
y = x ** 2
plt.plot(x, y)
plt.show()
지금까지 Boost였습니다.파이썬을 사용하여 C++로 작성한 샘플py::object np = py::import("numpy");
py::object plt = py::import("matplotlib.pyplot");
py::object x = np.attr("arange")(-10, 10, 0.1);
py::object y = x * x;
plt.attr("plot")(x, y);
plt.attr("show")();
(C++측은 직접 쓸 수 없기 때문에x ** 2
x * x
로 대체)
실행하면 다음 matplotlib을 통해 도표를 표시합니다.
참고 자료
#include <boost/python.hpp>
namespace py = boost::python;
int main()
{
Py_Initialize(); // 最初に呼んでおく必要あり
try
{
// Pythonで「print('Hello World!')」を実行
py::object global = py::import("__main__").attr("__dict__");
py::exec("print('Hello World!')", global);
}
catch (const py::error_already_set &)
{
// Pythonコードの実行中にエラーが発生した場合はエラー内容を表示
PyErr_Print();
}
return 0;
}
$ g++ main.cpp `pkg-config python3-embed --cflags --libs` -lboost_python38
$ ldconfig -p | grep "boost_python3"
다음은 각 구체적인 함수의 사용 방법을 살펴보자.
이후에는
namespace py = boost::python;
라고 쓰여 있다고 가정하고 py
로 표시한다.코드의
global
는 첫 번째 샘플과 마찬가지로 다음 코드를 통해 얻은 전역 이름 공간 대상입니다.py::object global = py::import("__main__").attr("__dict__");
■py:eval (): 파이톤으로 공식을 평가하고 결과를 되돌려줍니다
파이톤의 표현식을 문자열로 제시하면 결과는
py::object
형식으로 되돌아옵니다.아래와 같이
py::extract<型名>
조합은 C++ 형식으로 결과를 얻을 수 있다.// "2**3"の結果を取得
py::object result = py::eval("2**3", global);
// 結果をint型に変換して出力
std::cout << py::extract<int>(result) << std::endl;
실행 결과8
이 예에서는 파이썬 내 함수 등을 특별히 사용하지 않아 두 번째 매개변수의 네임스페이스global
를 생략해도 이동할 수 있습니다.그러나 두 번째 인자를 생략하면
pow
등 파이톤이 함수에 삽입되고 다른 사용자가 정의한 변수, 함수를 사용할 수 없음을 주의하십시오.■py:exec(): 문자열을 통한 파이썬 코드 실행 전달
첫 번째 견본과 같이
py::exec()
함수는 문자열에 파이톤 코드를 제공한 후 바로 실행됩니다.py::eval()
와 달리 여러 명령을 실행하거나 분류를 구분할 수 있습니다.py::exec(
"print('Hello!')\n"
"print('World!')", global);
실행 결과Hello!
World!
변수를 새로 만들면 두 번째 매개변수의 네임스페이스에 생성됩니다.// Pythonのグローバル名前空間内のresult変数に2**3を代入
py::exec("result = 2**3", global);
// 結果をint型に変換して出力
std::cout << py::extract<int>(global["result"]) << std::endl;
실행 결과8
■ py::exec_파일에서 Python 코드 실행하기
py::exec_file()
를 사용하면 파일 내용을 읽을 수 있으며 py::exec()
와 같이 실행할 수 있습니다.첫 번째 매개 변수는 Pythhon 스크립트의 파일 경로를 지정합니다.
py::exec_file("hello.py", global);
사용자 정의 클래스의 정의를 C++와 분리해서 Python 스크립트 파일로 준비하면 편리합니다.■py:object::attra():참조 객체의 필드/방법
py::object
의 필드(구성원 변수)나 방법(구성원 함수)은 attr()
함수를 사용할 수 있습니다.str형join 방법을 호출하는 예
// ['hoge','fuga','piyo']というリストを作成
py::object list = py::eval("['hoge','fuga','piyo']", global);
// 「','.join(list)」を実行し、リストの文字列をカンマ区切りで結合
py::object result = py::object(",").attr("join")(list);
// 結果を文字列型に変換して出力
std::string resultStr = py::extract<std::string>(result);
std::cout << resultStr << std::endl;
실행 결과hoge,fuga,piyo
■py:import():Python 라이브러리 사용
py::import
를 사용하면 파이톤의 import
문장과 같이 라이브러리를 가져올 수 있습니다.py::object np = py::import("numpy");
예를 들어 다음 Python 코드py::exec()
는 사용하지 않고 C++로 써 보세요.matplotlib에 y=x^2 도표의 견본을 표시합니다.
코드 샘플
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-10, 10, 0.1)
y = x ** 2
plt.plot(x, y)
plt.show()
지금까지 Boost였습니다.파이썬을 사용하여 C++로 작성한 샘플py::object np = py::import("numpy");
py::object plt = py::import("matplotlib.pyplot");
py::object x = np.attr("arange")(-10, 10, 0.1);
py::object y = x * x;
plt.attr("plot")(x, y);
plt.attr("show")();
(C++측은 직접 쓸 수 없기 때문에x ** 2
x * x
로 대체)실행하면 다음 matplotlib을 통해 도표를 표시합니다.
참고 자료
py::extract()
의 전환 예시Reference
이 문제에 관하여(C++에서 Python 코드 사용하기 (Boost.Python 사용)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/m4saka/items/1e2c24e80212a4c4c584텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)