ctypes
- 파이썬에서 DLL 로딩하여 dll 에서 제공하는 함수 호출 가능하게 하는 모듈.
- ctype 에서 dll 로딩위하여 cdll, windll, oledll 3종의 object 제공되며, dll의 함수호출규약 에 따라 아래와 같다.
-- cdll : 노출함수가 cdecl 호출규칙 적용된 dll 로드시 사용.
-- windll : 노출함수가 stdcall 호출규칙적용된 dll 로드시 사용.
-- oledll : stdcall 호출규칙및 윈도우 HRESULT 에러코드 반환하는 dll 로드시 사용.
사용예.
from ctypes import *
mydll = windll.LoadLibrary("d:\\mydll.dll") # dll 로딩. 절대 경로로 지정해야한다.
mydll.myfunction() # dll 제공함수 호출.
코드에서 dll 파일 절대경로 확보하여 LoadLibrary 호출하는 코드.
- 통상 내 파이썬 파일이 있는 동일 폴더에 dll 파일을 두고 사용하는데 이때 파일의 절대 경로를 코드내에서 구해서 LoadLibray 호출하는것이 훨씬 편리하다.
from ctypes import *
# dll 파일의 절대경로 경로 얻기.
import os.path
dll_name = "mydll.dll"
#이것사용하지마라. pyinstaller 로 exe 만든것을 실행시 경로 못찾는다. dllabspath = os.path.dirname(os.path.abspath(__file__)) + os.path.sep + dll_name
dllabspath = os.getcwd() + os.path.sep + dll_name # 경로구하기 이렇게 해야 exe 로 만든 경우에도 exe 있는 곳의 경로를 잡아낸다.
#print(dllabspath)
CLibCyAgent = windll.LoadLibrary(dllabspath) # dll loading.
자료형.
ctypes defines a number of primitive C compatible data types:
c_bool | _Bool | bool (1) |
c_char | char | 1-character bytes object |
c_wchar | wchar_t | 1-character string |
c_byte | char | int |
c_ubyte | unsigned char | int |
c_short | short | int |
c_ushort | unsigned short | int |
c_int | int | int |
c_uint | unsigned int | int |
c_long | long | int |
c_ulong | unsigned long | int |
c_longlong | __int64 or long long | int |
c_ulonglong | unsigned __int64 or unsigned long long | int |
c_size_t | size_t | int |
c_ssize_t | ssize_t or Py_ssize_t | int |
c_float | float | float |
c_double | double | float |
c_longdouble | long double | float |
c_char_p | char * (NUL terminated) | bytes object or None |
c_wchar_p | wchar_t * (NUL terminated) | string or None |
c_void_p | void * | int or None |
동영상. 파이썬에서 VC++로 제작된 DLL 실행예
- 상황예 : 2개의 DLL CyFinAPI.DLL,, CyFinForecast.DLL 을 파이썬에서 로딩하여 실행시키는 예.
- 참고 : 본예의 상황에서는 dll 측에서 __cdecl 형식으로 함수 노출시키든, __stdcall 형식으로 노출시키든 무관하게 cdll.Loadlibrary 나 windll.LoadLibrary 모두 정상작동하였음.
DLL 함수 호출시 인자로 포인터 전달
byref() 함수이용하든지, pointer() 함수이용하여 포인터 확보하여 DLL 함수 인자로 전달가능.
pointer()는 실제 포인터 객체를 생성하기 때문에 더 많은 작업을 수행하므로, 파이썬 자체에서 포인터 객체가 필요하지 않으면 byref()를 사용하는 것이 더 빠름.
i = c_int()
myDll.Func(byref(i)) #변수 i 의 포인터 전달됨.
DLL 함수호출시 인자로 함수포인터 전달
// myDLL.DLL 에서 아래와 같이 함수 포인터를 인자로 갖고 있는 경우.
void func(void(*pf)(int));
위 코드 처럼 - C 함수포인터 를 인자로 갖고있는 함수를 파이썬에서 호출하는 예.
from ctypes import *
mydll = windll.LoadLibrary(d:\\mydll.dll);
pypf=WINFUNCTYPE(None, c_int) #파이썬에서의 함수포인터
def pyfunc_cb(value): # dll 함수 func 로 전달할 파이썬 함수.
print("test")
mydll.func(pypf(pyfunc_cb)) #dll 함수 호출하면서 인자로 파이썬의 함수 pyfunc_cb 전달
다른예.
// DLL측 함수 인자3개 반환값있는것.
void RegiCallBack(int(*pf_cb)(int, double, double))
파이썬 코드.
from ctypes import *
mydll = windll.LoadLibrary(d:\\mydll.dll);
pypf1 = WINFUNCTYPE(c_int, c_int, c_double, c_double)
def OnReceive_Data_cb(i_symbol, price_ask, price_bid): # call back
print("call back")
return 1
mydll.RegiCallBack(pypf1(OnReceive_Data_cb))
ctypes 추가 상세정보
for pyhton 3.7.3
https://docs.python.org/3/library/ctypes.html
첫등록 : 2019년 4월 11일
최종수정 : 2022.01.27
본 글 단축주소 : https://igotit.tistory.com/2102
'지속가능티끌 > Python' 카테고리의 다른 글
Python. for in (0) | 2019.04.21 |
---|---|
Visual Studio 2019. 파이썬 개발환경 구축 (0) | 2019.04.18 |
PyCharm. 개요. 설치 (0) | 2019.04.08 |
Python. 프로젝트 만들기. hello python (0) | 2017.07.23 |
Python. 대화형 창 활용. hello python (0) | 2017.07.23 |
댓글