지속가능티끌/Python2019. 4. 11. 22:44

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"
dllabspath = os.path.dirname(os.path.abspath(__file__)) + os.path.sep + dll_name
#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

 

ctypes — A foreign function library for Python — Python 3.7.3 documentation

ctypes — A foreign function library for Python ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python. ctypes tut

docs.python.org


첫등록 : 2019년 4월 11일 

최종수정 : 2021.09.12

 

본 글 단축주소 : https://igotit.tistory.com/2102

 


 

Posted by 리치굿맨

댓글을 달아 주세요