Data+

Let's compile Python Source Code into DLL using Python Embedding

by Qerogram

서론

누리랩에서 공개한 "초간단 실시간 감시기 만들기(3)"(https://nurilab.github.io/2020/06/01/kicomav_driver_3) 포스팅에서 Python Embedding을 접하게 되었다. 개념은 알고 있었지만, 찾아봐도 이해가 잘 안되서 삽질을 꽤 많이 했다. 추후에도 이용할 것 같아서 간단하게 정리해서 공유하려고 한다.

 

Goal

Python Embedding을 통해 DLL 파일로 만들어서, C 계열로 작성된 다른 모듈에도 사용하자.

 

Requirement

"pyc"라는 확장자를 가진 컴파일된 파이썬 파일 혹은 파이썬 소스코드, Visual Studio, Python이 필요하다.

 

Set Environment

우선 IDE에서 프로젝트(DLL)를 하나 만든 뒤 Embedding을 할 수 있게끔, 관련 설정을 해준다.

[솔루션 뷰] -> [프로젝트] 명 우클릭 -> [속성] -> [구성 속성] -> [VC++ 디렉터리]로 이동한 뒤,

포함 디렉터리, 참조 디렉터리에 각각 %PythonPath%\Include, %PythonPath%\libs를 추가한다.

 

이후, [링커] -> [입력] -> 추가종속성에 python[버전].lib (세부 빌드는 중요하지 않음, 2.7.18 -> 2.7, 3.8.2 -> 3.8 등)을 추가한다.

 

How To

1. Python Code를 작성한다. 해당 함수가 호출되면, 메세지 박스가 나타나게 된다.

# qerogram.py
from ctypes import c_int, WINFUNCTYPE, windll
from ctypes.wintypes import HWND, LPCSTR, UINT
prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0)

def hello_qerogram() :
    MessageBox = prototype(("MessageBoxA", windll.user32), paramflags)

 

2. DLL을 작성한다. 설명이 필요한 부분은 아래와 같이 주석으로 작성해뒀으므로 참조.

// DLL SourceCode
#include "pch.h"
#include "Python.h" // Python Embedding을 위한 Header

extern "C" __declspec(dllexport) void qerogram() {
    PyObject* pName, * pModule;
    Py_Initialize();
    pName = PyString_FromString("qerogram"); // Python Embedding할 python Source Code or pyc 파일
    pModule = PyImport_Import(pName); // import qerogram

    if (pModule) {
        PyObject* pFunc = PyObject_GetAttrString(pModule, "hello_qerogram"); // qerogram.hello_qerogram()함수 찾기.
        PyObject* pValue = PyObject_CallObject(pFunc, NULL); // qerogram.hello_qerogram(NULL) 호출
    }
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

 

3. 사용할 C++ 소스 작성하자. DLL을 불러와서 사용해주면 된다.

// DLL Load Example
#include <stdio.h>
#include <Windows.h>

typedef void (*qerogram)();

int main() {
    HMODULE hModule = LoadLibraryA("qerogram.dll");
    qerogram q = (qerogram)GetProcAddress(hModule, "qerogram");
    q();
    return 0;
}

 

Conclusion

별 거 없는데, 처음에 이해가 안됐다. 그래도 익혀두면, 급할 때 교체해서 테스팅하기엔 좋은 것 같다.

실제로 활용하기에는 본문에서 사용된 함수만으로는 불편할 것이다. 따라서, 아래의 Reference에서 필요한 부분을 이용해 구현하면 된다.

[+] https://docs.python.org/ko/3/extending/embedding.html

'잡다한 것' 카테고리의 다른 글

Logstash grok test용 conf 파일  (0) 2021.03.31
KIBANA 설치  (0) 2021.03.25
mnist dataset 로드할 때, 503 error 해결방법  (0) 2021.03.18
Alfred SSH Plugin 개발  (0) 2020.05.29
쉘 스크립트로 mysql 쉽게 접속하기  (0) 2018.01.31

블로그의 정보

Data+

Qerogram

활동하기