-
파이썬을 사용해보자!Programming/C++ 2020. 4. 4. 19:59
안녕하세요. Teemol입니다.
오늘은 C++에서 Python을 사용하는 방법입니다.
먼저 아래의 링크에서 Python을 설치해야 합니다.
Downloads 탭에서 원하는 버전 / 플랫폼의 Installer를 받아서 설치합니다.
저는 Python 3.7.7 / Window x86 executable installer를 다운로드해서 진행하도록 하겠습니다.
설치 시 Customize installation에서 Download debug binaries를 체크하고 진행합니다.
*이 설정으로 디버그에서 사용하는 라이브러리를 받을 수 있습니다.
파이썬의 기본 설치 경로는 아래와 같습니다.
C:\Users\{User}\AppData\Local\Programs\Python
저는 아래와 같은 경로에 설치되었습니다.
C:\Users\Administrator\AppData\Local\Programs\Python\Python37-32
경로를 확인하는 이유는 헤더와 라이브러리를 가져오기 위해서입니다.
Python을 사용할 C++ 프로젝트에서 위의 경로에 있는 include 폴더와 libs 폴더를 각각 포함 디렉터리와 라이브러리 디렉터리에 추가합니다.
ex) 포함 디렉터리 > C:\Users\Administrator\AppData\Local\Programs\Python\Python37-32\include 라이브러리 디렉터리 > C:\Users\Administrator\AppData\Local\Programs\Python\Python37-32\libs
그리고 링커 > 입력 > 추가 종속성에 python37.lib를 추가합니다.
*버전에 따라 .lib 명이 다를 수 있습니다.
이제 프로젝트에 python37.dll과 python37_d.dll을 추가합니다.
*버전에 따라 .dll 명이 다를 수 있습니다.
이제 Python을 사용할 수 있습니다.
Python을 사용 시 아래의 내용을 추가하고 사용해야 합니다.
그렇지 않으면 Debug에서 제대로 동작하지 않을 수 있습니다.
#define HAVE_ROUND #ifdef _DEBUG #define RESTORE_DEBUG #undef _DEBUG #endif #include <Python.h> #ifdef RESTORE_DEBUG #define _DEBUG #undef RESTORE_DEBUG #endif
간단한 예제를 만들어 보겠습니다.
예제 1. 아래의 코드는 C++에서 Python의 함수를 호출하는 내용입니다.
더보기CPP CODE
PyObject* module_name, * module, * pFunc; Py_Initialize(); module_name = PyUnicode_FromString("Sample"); module = PyImport_Import(module_name); if (module == nullptr) { PyErr_Print(); std::cerr << "Fails to import the module.\n"; return 1; } Py_DECREF(module_name); pFunc = PyObject_GetAttrString(module, "Function"); Py_DECREF(module); PyObject_CallObject(pFunc, nullptr); Py_DECREF(pFunc); Py_Finalize();
PYTHON CODE (Sample.py)
def Function(): print("Hello Python!")
예제 2. 아래의 코드는 C++에서 Python의 Sample 클래스 안에 있는 함수인 두 개의 숫자를 받고 두 값을 더해서 돌려주는 함수를 호출하는 내용입니다.
더보기CPP CODE
PyObject* module_name, * module, * dict, * python_class, * object, * args, * func; Py_Initialize(); module_name = PyUnicode_FromString("Sample2"); module = PyImport_Import(module_name); if (module == nullptr) { PyErr_Print(); return 1; } Py_DECREF(module_name); dict = PyModule_GetDict(module); if (dict == nullptr) { PyErr_Print(); return 1; } Py_DECREF(module); python_class = PyDict_GetItemString(dict, "Sample"); if (python_class == nullptr) { PyErr_Print(); return 1; } Py_DECREF(dict); if (PyCallable_Check(python_class)) { object = PyObject_CallObject(python_class, nullptr); Py_DECREF(python_class); } else { Py_DECREF(python_class); return 1; } func = PyObject_GetAttrString(object, "Sum"); Py_DECREF(object); args = PyTuple_New(2); PyTuple_SetItem(args, 0, PyLong_FromLong(1)); PyTuple_SetItem(args, 1, PyLong_FromLong(2)); PyObject* value = PyObject_CallObject(func, args); Py_DECREF(args); Py_DECREF(func); long result = PyLong_AsLong(value); Py_DECREF(value); Py_Finalize();
PYTHON CODE (Sample2.py)
class Sample: def Sum(self, num1, num2): return ( num1 + num2 )
함수의 첫 번째 인자 self는 아래와 같은 방식으로 사용하지 않을 수 있습니다.
class Sample: @staticmethod def Sum(num1, num2): return ( num1 + num2 )
마지막으로 Python을 포함해서 배포하는 방법입니다.
Python Installer를 받은 곳에서 embeddable zip file을 다운로드합니다.
ex) Windows x86 embeddable zip file
해당 파일을 받아서 압축을 풀면 또 하나의 .zip 파일이 있습니다.
저는 python37.zip 파일이 있습니다.
*버전에 따라 .zip 명이 다를 수 있습니다.
python37.zip 파일을 배포할 응용프로그램이 있는 폴더로 이동 후 Python을 사용하는 코드의 시작 부분에 아래의 내용을 추가합니다.
//ADD Py_SetPythonHome(L"python37"); Py_Initialize(); module_name = PyUnicode_FromString("Sample2");
SetPythonHome(L"python37")을 추가하였습니다.
위 내용을 추가하고 빌드 한 뒤 응용프로그램을 배포할 때 python37.zip을 같이 배포하면 Python이 설치되어 있지 않아도 Python을 사용할 수 있습니다.
*주의사항
Python 파일명이 Lib에 있는 파일명과 동일하면 Lib의 내용을 먼저 읽어서 제대로 동작하지 않습니다.
ex) test.py, abc.py 등
- 끄읕
'Programming > C++' 카테고리의 다른 글
구조체 크기! (0) 2020.06.08 [MFC] CString -> string 변환 (0) 2020.01.31 예외 처리를 해보자 (0) 2019.12.16 Dumpbin을 사용해보자! [Dependents, Headers] (0) 2019.09.24