C++ Embedded Python
C++ Embedded Python 이란,
C++ 애플리케이션 내부에 CPython 인터프리터를 내장하고
Python C API 또는 pybind11을 통해 Python 코드를 실행하는 구조를 의미한다.
Python C API vs. pybind11 비교
- pybind11 은 Python C API 호출을 C++ 스타일로 래핑하여 제작된 헤더온리 C++ 러이브러리.
- pybind11 에서 11 의 의미는 C++11 표준을 적극적으로 사용했다는 의미.
- C++ 프로그램에서 Pyhton 실행만 필요하고 간단하게 활용하는 경우에는 Python C API 만으로 충분.
- C++ 프로그램에서 파이썬 측 함수호출 , 구조체 반환 등 많은 인터페이스가 요구되는 경우에는 pybind11 이 유리.
[C++ 코드]
└─ pybind11
└─ Python C API
└─ CPython Interpreter
| 항목 | Python C API | pybind11 |
| 공식성 | CPython 공식 | 서드파티 |
| 추상화 | 매우 낮음 | 높음 |
| 코드 가독성 | 낮음 | 매우 좋음 |
| 예외 처리 | 수동 | 자동 |
| GIL 처리 | 직접 | 헬퍼 제공 |
| 성능 | 동일 | 동일 (오버헤드 거의 0) |
pybind11
- 필수 요구조건 : CPython 3.8 이상. C++11 이상.
- 아래와 같은 핵심 C++ 기능을 Python으로 매핑가능.
- Functions accepting and returning custom data structures per value, reference, or pointer
- Instance methods and static methods
- Overloaded functions
- Instance attributes and static attributes
- Arbitrary exception types
- Enumerations
- Callbacks
- Iterators and ranges
- Custom operators
- Single and multiple inheritance
- STL data structures
- Smart pointers with reference counting like std::shared_ptr
- Internal references with correct reference counting
- C++ classes with virtual (and pure virtual) methods can be extended in Python
- Integrated NumPy support (NumPy 2 requires pybind11 2.12+)
pybind11 상세 도움말 : https://pybind11.readthedocs.io/en/latest/
pybind11 다운로드
주소 : https://github.com/pybind/pybind11
VC++ 프로젝트에서 pybind11 활용하는 경우 필요한 것은 include/pybind11 폴더 에 있는 파일만 있음 충분하다.
git clone 으로 받아도 되고 zip 파일 다운로드 해서 include 폴더만 남기고 다른 건 모두 삭제해도됨.

작업 폴더로 복사.
통상 다운받은 소스들은 프로젝트에서 직접 접근하지 않고 작업 폴더로 복사해서 활용한다.
include/pybind11 의 모든 파일을 내 작업폴더로 복사했다.

VC++ 프로젝트 소스에서 헤더파일 include 하기
- pybind11 은 헤더파일 로만 구성되어있어 간단함.
- pybind11 활용 코드를 바로 main application 에서 구현하지 않고 내가 사용하기 편한 형식으로 클래스 CCyUtilPyBind 부터 생성 하고 main application 에서는 CCyUtilPyBind 클래스 활용하기로 한다.

VC++ 프로젝트 속성창에서 include 경로 추가하기

파이썬 관련 파일처리
pybind11 파일들에서 아래와 같은 파이썬 관련 파일을 include 하고 있다.
#include <Python.h>
#include <frameobject.h>
#include <pythread.h>
이 파일들은 파이썬 설치 경로에 있는 include 폴더 하위에 있으며 내 프로젝트에서 관리하기 좋은 경로에 복사해서 활용하기로 한다. 본 예에서는 파이썬 버전 3.12.5 설치된 것에서 inlcude, libs 를 복사해왔다. 폴더명에는 필수 파이썬 버전을 기록해둬야 이후 다른 버전의 파이썬으로 변경시 혼선 최소화 된다.

VC++ 프로젝트에서 파이썬 헤더 파일 inlcude 경로 추가.

VC++ 프로젝트에서 파이썬 lib 링커 처리
- 프로젝트 속성 링커 부분에 설정하지 않아도 된다. 아래처럼 #pragma comment () 구문 기록하면 훨씬 편리하다.

여기까지 pybind11 활용한 코딩 가능 상태 셋팅 완료.
static py::scoped_interpreter guard{};
CPython 인터프리터 전체를 프로세스에 초기화하는 역할을 하며,
Python 인터프리터 코어는 완전히 준비된다.
- Py_Initialize() 호출
- GIL 생성
- 메인 스레드 등록
- sys, builtins, __main__ 생성
- sys.path 기본값 세팅
- Python 메모리 관리 시스템 활성화
즉, CPython 인터프리터가 완전히 기동됨
C++ 프로세스 생성시 1회만 실행한다. 프로세스 종료시 파이썬 관련 제거 처리도 이뤄진다. 프로세스 중에 반복 호출하지 않는다.
Embedded Python 환경에서는 Python 인터프리터를 명시적으로 종료하지 않는 것이 정석이며,
pybind11::scoped_interpreter 가 프로세스 생명주기 전체를 관리하도록 두는 것이 가장 안전하다.
실행예
아래 화면의 작은 메시지 박스가 파이썬에서 실행된것.

코드
void CCyUtilPyBind::Test_ctypes_messagebox()
{
//py::gil_scoped_acquire gil;
// R"()": raw string literal (원시 문자열 리터럴)
// Python 코드를 C++ 문자열로 바로 쓰고 싶으면 R"()" 이용한다.
// \n, \t, \\ 등을 그대로 문자열로 사용 가능. Python 코드처럼 \가 많이 나오는 경우 유용
// 큰따옴표 안에 큰따옴표 가능
// 여러 줄 문자열 가능. 여러 줄 Python 코드 그대로 넣기 편함
// R"delimiter( … )delimiter" // 시작 끝 구분자(아무문자나 시작과 끝에 부착하면됨. 이것 표기하면 문자열에 내부에 )" 있는것도 표현가능.
// R"(파이썬 문법 그대로 들여쓰기 기준 만족해야하며 좌측 정렬 유지할것)"
const char* code_python =
R"DELIM(
import ctypes
ctypes.windll.user32.MessageBoxW(0,"Hello from embedded Python","Python",0)
)DELIM";
// 함수 정의하고 실행 예.
/*
const char* code = R"(
def show_msg():
import ctypes
ctypes.windll.user32.MessageBoxW(0,"Hello from embedded Python","Python",0)
show_msg()
)";
*/
std::string str_error;
Exec(code_python,str_error);
}
실행파일 있는 폴더 구조
MyApp/
├─ MyApp.exe
├─ python311.dll
├─ python311.zip
├─ Lib/
│ └─ site-packages/
│ └─ MetaTrader5/
└─ scripts/
- Python embedded distribution 사용
- 시스템 Python 불필요
- EXE 폴더 안에서 Python 구동
파이썬 Windows embeddable package
- Embedded Pyhton 활용하여 제작된 C++ 프로그램이 대상 PC 에 Python 을 별도로 설치하지 않아도 실행될 수 있도록 Python 런타임을 함께 배포하기 위해 제공되는 패키지이다.
https://www.python.org/downloads/windows/
embeddable package 압축풀면 보통 아래 폴더 구조이다.
python311/
├─ python311.dll
├─ python311.zip
├─ python311._pth
파일 전부를 C++ 실행파일 있는 경로 예 MyApp/python/ 에 그대로 복사한다.
MyTradingApp/
│
├─ MyTradingApp.exe ← C++ 실행 파일
├─ OrderBridge.dll ← (나중에 분리될 DLL, 지금은 exe에 포함)
│
├─ python/ ← Python embeddable package 루트
│ ├─ python311.dll
│ ├─ python311.zip ← 표준 라이브러리
│ ├─ _pth file (선택) ← python311._pth
│ │
│ └─ Lib/
│ └─ site-packages/
│ ├─ MetaTrader5/
│ ├─ numpy/
│ └─ 기타 패키지
│
├─ scripts/ ← 내가 작성한 Python 코드
│ ├─ order_bridge.py
│ └─ __init__.py
│
├─ config/
│ └─ app.ini
│
└─ logs/
└─ app.log
python311._pth 파일 처리
- 이 파일이 있으면 sys.path 를 강제로 제한하고, site-package 자동로딩도 안된다.
이 파일을 아예 삭제하고 C++ 코드 내에서 명시적으로 Python 경로를 초기화 하는 방식이 좋다.
아래 코드에서 함수 Py_SetPath();
C++ 코드에서 파이썬 경로 설정
Py_SetPythonHome(L".\\python");
Py_SetPath(
L".\\python\\python311.zip;"
L".\\python\\Lib;"
L".\\python\\Lib\\site-packages;"
L".\\scripts"
);
상위 정리
Visual Studio , Visual C++ 활용 정리.
Visual Studio C++ 활용 Visual StudioVisual C++ / C#1.설치, 설정 주제 비고. Visual Studio 2010 설치. Visual Studio 2013 (Community)무료 설치. Visaul Studio 2015 (Community)무료 설치.- Visual Studio 2015 버전은 이전 버전대비 급
igotit.tistory.com
첫 등록 : 2026.01.04
최종 수정 : 2026.01.24
단축 주소 : https://igotit.tistory.com/6361
'VisualStudio.C++.C# > C . C++' 카테고리의 다른 글
| C++ . 네임스페이스 (0) | 2026.01.18 |
|---|---|
| VC++ 프로젝트 폴더 복사하여 작업 하는 경우 필수 삭제 해야할 것 (0) | 2025.04.09 |
| std::shared_mutex . 멀티 스레드 읽기 쓰기 락 (0) | 2024.09.12 |
| C/C++ . 부호 있는 정수 singed int . 음수 표현 규격 . 2's complement (0) | 2023.08.27 |
| C/C++ . volatile 변수 (0) | 2023.03.10 |
댓글