사용한 개발환경
Windows 10 Home 64bit
Qt 5.12.3
python v3.5.0 64bit
절차
Qt 프로젝트 파일 설정
Qt의 프로젝트 파일(.pro)에 설치된 python의 경로를 아래와 같이 INCLUDEPATH와 LIBS를 지정해준다.
(python3가 C:/Python35/ 에 설치되었다고 가정하면,)
....
FORMS += \
DlgMain.ui
INCLUDEPATH = C:\Python35\include
LIBS += -LC:\Python35\libs -lpython35
# Default rules for deployment.
....
slots 키워드 충돌 방지
python.h 헤더파일과 Qt의 slots 키워드가 충돌한다. 이를 방지하기 위해, python.h를 직접 include하지 말고 wrapper header를 만들어 include하자.
python_wrapper.h
#pragma once
// [Python/C API] Debug 빌드 시, "Python27_d.lib" 에러
// https://kiya.tistory.com/2
// (pyconfig.h, object.h 수정 필요)
// https://stackoverflow.com/questions/23068700/embedding-python3-in-qt-5
# pragma push_macro("slots")
# undef slots
# define PY_SSIZE_T_CLEAN
# include <Python.h>
# pragma pop_macro("slots")
디버그 모드 링크에러 방지
디버그 모드로 링크하면 python35_d.lib를 링크하려고 시도하는데, 이 파일은 python 소스코드를 내려받아 빌드해야 만들 수 있다. 임시로 python35.lib로 대체하기 위해 python의 include/ 폴더에 아래 2가지 조치를 한다.
1) pyconfig.h 파일에서 아래와 같이 python35_d.lib를 python35.lib로 교체
# if defined(_DEBUG)
//# pragma comment(lib,"python35_d.lib")
# pragma comment(lib,"python35.lib")
# elif defined(Py_LIMITED_API)
# pragma comment(lib,"python3.lib")
# else
# pragma comment(lib,"python35.lib")
# endif /* _DEBUG */
2) object.h 파일에서 #define Py_TRACE_REFS 리마크
/* Py_DEBUG implies Py_TRACE_REFS. */
#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
//#define Py_TRACE_REFS
#endif
python 스크립트 실행 함수 구현
run_py.cpp
#include "python_wrapper.h"
#include <stdio.h>
/** --------------------------------------------------------
@param[in] pathname python script의 경로파일명 (.py 포함)
@return
- 0 OK
- -1 file 열기 실패
- <0 error code
@brief Very High Level Embedding 방식으로 python script 실행
-------------------------------------------------------- */
int run_python(const char* pathname)
{
//Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
FILE* fp = nullptr;
auto ret = fopen_s(&fp, pathname, "r");
if(ret != 0) return -1;
auto iret = PyRun_SimpleFile(fp, pathname);
if(iret < 0) return iret;
Py_Finalize();
fclose(fp);
return 0;
}
빌드와 실행
간단한 .py를 작성해 실행해본다.
hello.py
#-*- encoding: utf-8 -*-
print('hello, world!')
test.cpp
auto iret = run_python("D:/test/hello.py");
if (iret<0) return iret;
QtCreator에서 release로 빌드하여 실행해보면 .py 스크립트가 정상적으로 실행된다.
출력 문자열은 QtCreator의 Application Output에서 볼 수 있다.
그러나 debug 모드에서는 아래와 같이 예외가 발생한다. python 라이브러리가 debug 용이 아니라서 그런 것 같다.
배포
python3가 설치되지 않은 시스템에 배포할 때는, python 폴더 내에 있는 python35.dll 파일을 복사하여 실행파일과 같은 폴더에 함께 배치해 줘야 한다.
참고자료
https://docs.python.org/ko/3/extending/embedding.html
1. 다른 응용 프로그램에 파이썬 내장하기 — Python 3.8.2 문서
1. 다른 응용 프로그램에 파이썬 내장하기 이전 장에서는 파이썬을 확장하는 방법, 즉 C 함수의 라이브러리를 파이썬에 연결하여 파이썬의 기능을 확장하는 방법에 관해 설명했습니다. 다른 방법도 가능합니다: 파이썬을 내장시켜 C/C++ 응용 프로그램을 풍부하게 만들 수 있습니다. 내장은 C 나 C++가 아닌 파이썬으로 응용 프로그램의 일부 기능을 구현하는 능력을 응용 프로그램에 제공합니다. 이것은 여러 목적으로 사용될 수 있습니다; 한 가지 예는 사용자가 파
docs.python.org
[Python/C API] Debug 빌드 시, "Python27_d.lib" 에러
Python/C API를 사용하기위해, 1. Python.h를 include 2. Python27.lib을 추가해야 한다. 하지만, Debug모드 빌드 시 LINK : fatal error LNK1104: cannot open file 'python27_d.lib 에러가 발생 구글링 결과 해..
kiya.tistory.com
https://stackoverflow.com/questions/23068700/embedding-python3-in-qt-5
Embedding Python3 in Qt 5
I would like to embed Python interpreter 3.4 into a Qt 5.2.1 application (64-bit). However I'm having build issues, I mean when I include Python header in the main.cpp it compiles fine. #include <
stackoverflow.com
'programming > python' 카테고리의 다른 글
matplotlib의 plot() 실행 시, kernel shutdown 될 때 대응 방법 (0) | 2024.03.10 |
---|---|
함수 매개변수 문법 정리 - python과 javascript (0) | 2019.12.20 |