ABOUT ME

-

  • 파이썬을 사용해보자!
    Programming/C++ 2020. 4. 4. 19:59

    안녕하세요.  Teemol입니다.

    오늘은 C++에서 Python을 사용하는 방법입니다.

     

    먼저 아래의 링크에서 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.dllpython37_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

    댓글

Designed by Tistory.