파이썬 스터디 9장  C/C++ 연동    Ahn Seong Hyun
확장모듈•   파이썬에서 C/C++라이브러리 함수 또는 시스템 콜을 할 수 있는 새로운 내장객체 타입 구현•   하드웨어를 제어하는 경우 C기반이 많고 빠르다.•   처리 속도는 연산량이 많아지면, 파이썬에 비해서 C가...
간단한 예제 strlen() 함수를 파이썬에서 써보자.1.   C 모듈 만들기     - spammodule.c (모듈이름 + module.c) 작성주의사항     -   헤더파일 include 시, python.h ...
간단한 예제2. 모듈 초기화-   파이썬 내에서 1) 모듈을 찾고, 2) 초기화를 하고, 3) 지역 이름공간에 이름을 정의 하기    때문에, C/C++ 모듈에서 2단계와 3단계 부분이 구현이 되어야 함.-   Py_I...
간단한 예제3. 모듈 빌드윈도우 빌드: 비주얼 스튜디오 이용해서 Dll생성설정(프로젝트 속성창)- C/C++의 일반탭에서 추가포함 디렉토리에서 Python.h가 있는 디렉토리 지정- 링커 -> 일반메뉴에서 추가라이브러리...
간단한 예제3. 모듈 빌드리눅스 빌드: 입력기를 통해서 spammodule.c 작성후, distutils를 이용해서 간단히 빌드: 189p
파이썬/C API파이썬/C API : 파이썬 자료형을 C언어에서 사용하게 하겠다.    PyArg_ParseTuple() 함수      int PyArg_ParseTuple(PyObject *arg, char *for...
파이썬/C API   Py_BuildValue() 함수     PyObject *Py_BuildValue(char * format…);-   C의 자료형을 파이썬의 자료형으로 변환-   단, 포인터형은 변환할수 없음....
에러처리 파이썬/C API 함수들은 이미 내부적으로 예외처리 되어 있음. 사용자 정의의 C/C++ 함수에서 에러상태 설정과 에러값(NULL) 리턴 Void PyErr_SetString(PyObject *type, ...
참조카운트• C/C++ 에서의 동적 메모리 할당- C : malloc, free- C++ : new, delete   파이썬 메모리 관리 방식 = 가비지컬렉션-   객체의 레퍼런스가 필요할때마다 새로운 공간 확보 하지...
참조카운트•   참조카운트를 위한 2개의 매크로 함수-   Py_INCREF() : 참조 카운트 증가-   Py_DECREF() : 참조 카운트 감소 및 메모리 해제   언제 사용해야 하는가?              ...
참조카운트 레퍼런스 소유권 법칙•   파이썬 C API 함수-   함수마다 레퍼런스 전달 방식이 다르다.-   레퍼런스의 소유권한을 넘겨주거나, 빌려주거나.   레퍼런스 소유권 이전 함수-   PyLong_FromL...
참조카운트 레퍼런스 소유권 법칙 PyObject* Py_BuildValue(const char *format, ...)¶ Return value: New reference. Create a new value based...
참조카운트 레퍼런스 소유권 법칙함수 매개변수로 이용 시, 빌려온 레퍼런스로 전달된다.    tuple = PyTuple_GetItem(list, 1); //tuple-빌려온 레퍼런스, Py_INCREF 호출할 필요없음...
참조카운트 레퍼런스 소유권 법칙   예외•   PyTuple_SetItem( )와 PyList_SetItem( )함수는 소유권한을 빼앗아 갑니다. (함수 호출이    실패 해도 빼앗아 갑니다)    Note : Th...
참조카운트 레퍼런스 소유권 법칙   예외   빌려온 레퍼런스라도 Py_INCREF( )를 반드시 해줘야 하는 경우    - 호출한 쪽에서 소유권을 유지하고 싶을 경우      void bug(PyObject* li...
참조카운트 레퍼런스 소유권 법칙   NULL 검사    PyObject *item = NULL;    ...    Py_DECREF(item);-   NULL 인 경우, Py_DECREF() 를 호출하면 어떻게 되나...
확장 타입• C를 이용해서 모듈 뿐만 아니라, 파이썬의 리스트 같은 타입 작성 가능.• 파이썬에서 쓸수 있는 새로운 자료형을 C에서 만들어서 쓸수 있다.•   타입 정의•   타입내 인스턴스 변수 정의•   생성자, 소...
ctypes외부 라이브러리 호출을 위한 완전 간단한 방법이 있다.파이썬에서 제공하는 ctypes 모듈을 사용.-    파이썬의 외부 함수 인터페이스(FFI) 라이브러리로, 파이썬 2.5부터 기본으로 포함되어 있다. 윈도...
ctypes         ctypes type                  C type                         Python type     c_bool            _Bool        ...
ctypes• 사용자 정의 라이브러리 연동하기- 윈도우/리눅스에서 모듈 생성 윈도우•   C:Windowssystem32 폴더로 test.dll 파일을 복사합니다.•   >>> from ctypes import *  ...
ctypes• 사용자 정의 라이브러리 연동하기- 윈도우/리눅스에서 모듈 생성 리눅스•   dynamic library로 만듭니다.    gcc -shared libtest.o -o libtest.so•   터미널에서 ...
파이썬 스터디 9장
Upcoming SlideShare
Loading in...5
×

파이썬 스터디 9장

2,917

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
2,917
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
21
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

파이썬 스터디 9장

  1. 1. 파이썬 스터디 9장 C/C++ 연동 Ahn Seong Hyun
  2. 2. 확장모듈• 파이썬에서 C/C++라이브러리 함수 또는 시스템 콜을 할 수 있는 새로운 내장객체 타입 구현• 하드웨어를 제어하는 경우 C기반이 많고 빠르다.• 처리 속도는 연산량이 많아지면, 파이썬에 비해서 C가 빠르다.• 반드시, C/C++ 에서 #include “python.h” 필요.
  3. 3. 간단한 예제 strlen() 함수를 파이썬에서 써보자.1. C 모듈 만들기 - spammodule.c (모듈이름 + module.c) 작성주의사항 - 헤더파일 include 시, python.h 를 제일 먼저 포함시켜야 함. - python.h 내부에는 기본적으로 <stdio.h><string.h><error.h><limits.h><stdlib.h> 포함.
  4. 4. 간단한 예제2. 모듈 초기화- 파이썬 내에서 1) 모듈을 찾고, 2) 초기화를 하고, 3) 지역 이름공간에 이름을 정의 하기 때문에, C/C++ 모듈에서 2단계와 3단계 부분이 구현이 되어야 함.- Py_InitModule() : 모듈 초기화에 사용- 확장모듈 호출시, PyInit_spam() 함수 실행 (형식 준수 PyInit_<module_name>)- 파이썬 인터프리터에서 import시, 맨 처음 PyInit_<module_name>()를 찾아서 실행하는 구조- PyModule_Create() : 생성할 모듈 생성정보를 담고 있는 구조체를 가지고 모듈 생성 : 생성후 해당 모듈 객체의 포인터를 반환하고 에러 발생시, NULL반환 : 이것을 가지고 sys.module 에 모듈을 등록한다.
  5. 5. 간단한 예제3. 모듈 빌드윈도우 빌드: 비주얼 스튜디오 이용해서 Dll생성설정(프로젝트 속성창)- C/C++의 일반탭에서 추가포함 디렉토리에서 Python.h가 있는 디렉토리 지정- 링커 -> 일반메뉴에서 추가라이브러리 디렉토리에서 python30.lib가 있는 디렉토리 지정- 링커 -> 일반 -> 입력- 명령줄 메뉴 하단의 추가옵션에 /expo추가종속성 python30.lib rt:PyInit_spam 입력- 링커 -> 일반 출력파일의 확장자를 pyd로 변경주의사항- 빌드 옵션에서 릴리즈 모드로 빌드- 파이썬 설치시 기본제공되는 lib는 디버그 용이 아닌 릴리즈용.- 비주얼스튜디오 설정은 파이썬 설치 버전에 따라 변경되오니, 잘 살필것.
  6. 6. 간단한 예제3. 모듈 빌드리눅스 빌드: 입력기를 통해서 spammodule.c 작성후, distutils를 이용해서 간단히 빌드: 189p
  7. 7. 파이썬/C API파이썬/C API : 파이썬 자료형을 C언어에서 사용하게 하겠다. PyArg_ParseTuple() 함수 int PyArg_ParseTuple(PyObject *arg, char *format...);1) 파이썬에서 전달된 변수2) PyObject를 어떤 형으로 변환할것인지 지정3) 변환한 값을 받을 변수 지정- i, s, f, l, y, u, O, S 등 다양한 형 지정가능(190p)- s#과 같이 #을 붙이면 문자열과 문자열 길이를 자동 변환- 여러개의 기호를 묶어서 포맷으로 설정.- PyObject에 대한 타입 검사 함수들 존재(191p)
  8. 8. 파이썬/C API Py_BuildValue() 함수 PyObject *Py_BuildValue(char * format…);- C의 자료형을 파이썬의 자료형으로 변환- 단, 포인터형은 변환할수 없음.- Py_BuildValue()비어 있으면, 자동으로 None 을 만든다.
  9. 9. 에러처리 파이썬/C API 함수들은 이미 내부적으로 예외처리 되어 있음. 사용자 정의의 C/C++ 함수에서 에러상태 설정과 에러값(NULL) 리턴 Void PyErr_SetString(PyObject *type, const char *message); 1) 예외 타입 2) 에러에 대한 메시지 PyErr_SetFromErrno() 문자열 대신 C전역변수인 errno값을 반환
  10. 10. 참조카운트• C/C++ 에서의 동적 메모리 할당- C : malloc, free- C++ : new, delete 파이썬 메모리 관리 방식 = 가비지컬렉션- 객체의 레퍼런스가 필요할때마다 새로운 공간 확보 하지 않음.- 타입에 대한 인스턴스 레퍼런스 카운트를 통한 객체 참조 전략.- 모든 객체는 자신이 참조된 횟수를 관리하는 카운터를 가지고 있고, 객체가 참조될 때마다 카운터를 하나씩 증가시키고, 참조가 해제 될 때 마다 레퍼런스 카운터를 하나 감소시킨다.- 만약 카운터가 0이 되면 그때서야 객체는 메모리 공간에서 삭제된다. 파이썬 – C/C++ 연동이기 때문에, C/C++ 에서 개발자가 객체 참조 카운트 증분에 대해서 구현
  11. 11. 참조카운트• 참조카운트를 위한 2개의 매크로 함수- Py_INCREF() : 참조 카운트 증가- Py_DECREF() : 참조 카운트 감소 및 메모리 해제 언제 사용해야 하는가? 파이썬에서는 어떤 것도 객체를 소유할 수 없고, 단지 객체의 참조(reference)만을 가질 수 있다- 레퍼런스를 사용하고 있는 곳에서는 레퍼런스를 생성하고,- 더 이상 필요 없을 경우 Py_DECREF( )를 호출해줘야 메모리 누수가 일어나지 않는다. >>> setList = [ ] #사전 객체(setList)의 레퍼런스 생성 >>> borrow_ref = setList #borrow_ref는 setList와 똑 같은 레퍼런스를 가리키고 있음- 빌려온 경우, 증가 감소 해주면 안된다.
  12. 12. 참조카운트 레퍼런스 소유권 법칙• 파이썬 C API 함수- 함수마다 레퍼런스 전달 방식이 다르다.- 레퍼런스의 소유권한을 넘겨주거나, 빌려주거나. 레퍼런스 소유권 이전 함수- PyLong_FromLong()/ Py_BuildValue() 레퍼런스 소유권 빌려주는 함수- PyTuple_GetItem( ), PyList_GetItem( ), PyDict_GetItem( ), PyDict_GetItemString()- 튜플, 리스트, 사전과 관련된 함수들은 빌려온 레퍼런스를 넘겨준다. 파이썬 매뉴얼을 볼 수 밖에 없다.
  13. 13. 참조카운트 레퍼런스 소유권 법칙 PyObject* Py_BuildValue(const char *format, ...)¶ Return value: New reference. Create a new value based on a format string similar to those accepted by the PyArg_Parse*() family of functions and a sequence of values. Returns the value or NULL in the case of an error; an exception will be raised if NULL is returned.- Py_BuildValue 는 매뉴얼을 보면 반환값을 새로운 레퍼런스를생성해서 내보내고 있음.
  14. 14. 참조카운트 레퍼런스 소유권 법칙함수 매개변수로 이용 시, 빌려온 레퍼런스로 전달된다. tuple = PyTuple_GetItem(list, 1); //tuple-빌려온 레퍼런스, Py_INCREF 호출할 필요없음 Py_INCREF(list) // 참조카운트를 증가시켜lifetime 보장시켜줌 long l = 0; PyObject* item = PyLong_FromLong((long)l); //item은 new reference … Py_DECREF(item) //따라서, => 참조카운터감소!!! Py_DECREF(list) // list의참조카운터감소- 함수로 전달된 인자는 모두 ‘빌려온’ 레퍼런스, 따라서 Py_DECREF(list) 시키면 안된다.- 한 곳에서 함수가 정상적으로 수행될 때까지 빌려온 레퍼런스의 lifetime을 보장해줘야 한다. 그러기 위해서는 Py_INCREF( )를 호출해 참조 카운트를 하나 증가시켜서 사용해야 한다.- 호출한 쪽에서 소유권을 넘겨 받았으면 반드시 Py_DECREF( )를 호출해주고, 빌려온 레퍼런스라도 호출한 쪽에서 소유권을 유지하고 싶으면 Py_INCREF( )를 사용해야 한다.
  15. 15. 참조카운트 레퍼런스 소유권 법칙 예외• PyTuple_SetItem( )와 PyList_SetItem( )함수는 소유권한을 빼앗아 갑니다. (함수 호출이 실패 해도 빼앗아 갑니다) Note : This function “steals” a reference to item and discards a reference to an item already in the list at the affected position. list = PyList_GetItem(list, 1); long l = 0; PyObject* item = PyLong_FromLong((long)l); PyList_SetItem(list, l, item); #Py_DECREF(item)을 하면 안됩니다. item의 소유권을 뺏겻어요!
  16. 16. 참조카운트 레퍼런스 소유권 법칙 예외 빌려온 레퍼런스라도 Py_INCREF( )를 반드시 해줘야 하는 경우 - 호출한 쪽에서 소유권을 유지하고 싶을 경우 void bug(PyObject* list) { PyObject* item = PyList_GetItem(list, 0); PyList_SetItem(list, 1, PyLong_FromLong(0L)); PyObject_Print(item, stdout, 0); }- Item 에 list[0]을 저장. 그리고 SetItem 이용 list[1] =0 대입, PyObject_Print(item, stdout, 0); 에서 오류 발생 가능성 있음.- Setitem 을 하는 과정에서 list 내 모든 아이템에 대한 레퍼런스를 재배치 하는 과정이 있을수가 있다. 즉, 모든 레퍼런스를 삭제하고, 다시생성.- 레퍼런스 카운트를 증가시켜서 item 이 가지고 있는 레퍼런스가 삭제되지 않도록 해야함.
  17. 17. 참조카운트 레퍼런스 소유권 법칙 NULL 검사 PyObject *item = NULL; ... Py_DECREF(item);- NULL 인 경우, Py_DECREF() 를 호출하면 어떻게 되나?• 파이썬에서는 해당 레퍼런스가 NULL인지를 체크하는 매크로 함수가 없음.• Py_XINCREF( )와 Py_XDECREF( )는 내부에 NULL혹은 None인지를 검사하고 NULL일 경우 참조 카운트에 대한 작업을 수행하지 않는다. PyObject *item = NULL; ... Py_XDECREF(item);
  18. 18. 확장 타입• C를 이용해서 모듈 뿐만 아니라, 파이썬의 리스트 같은 타입 작성 가능.• 파이썬에서 쓸수 있는 새로운 자료형을 C에서 만들어서 쓸수 있다.• 타입 정의• 타입내 인스턴스 변수 정의• 생성자, 소멸자 정의• 사용자 함수 정의• 198p
  19. 19. ctypes외부 라이브러리 호출을 위한 완전 간단한 방법이 있다.파이썬에서 제공하는 ctypes 모듈을 사용.- 파이썬의 외부 함수 인터페이스(FFI) 라이브러리로, 파이썬 2.5부터 기본으로 포함되어 있다. 윈도의 DLL과 같은 동적 라이브러리에 있는 함수를 직접 호출할 수 있으며, 다양한 C 자료형을 다루기 위한 인터페이스를 제공한다. 이를 사용해 순수 파이썬 코드만으로 확장 모듈을 구현할 수도 있다. >>> from ctypes import * >>> printf = cdll.msvcrt.printf >>> printf("hello worldn") hello world 12 >>> printf.restype = None >>> printf("hello worldn") hello world- 윈도우 환경의 printf 함수를 가져와서 사용하는 예제- C의 데이터 타입을 바로 쓸 수 가 있다. (213P)- 윈도우의 메시지 박스도 ctypes를 통해서 랩핑해서 사용할 수 있다.http://docs.python.org/library/ctypes.html
  20. 20. ctypes ctypes type C type Python type c_bool _Bool bool (1) c_char char 1-character string c_wchar wchar_t 1-character unicode string c_byte char int/long c_ubyte unsigned char int/long c_short short int/long c_ushort unsigned short int/long c_int int int/long c_uint unsigned int int/long c_long long int/long c_ulong unsigned long int/long c_longlong __int64 or long long int/long unsigned __int64 or unsigned long lo c_ulonglong int/long ng c_float float float c_double double float c_longdouble long double float c_char_p char * (NUL terminated) string or None c_wchar_p wchar_t * (NUL terminated) unicode or None c_void_p void * int/long or None
  21. 21. ctypes• 사용자 정의 라이브러리 연동하기- 윈도우/리눅스에서 모듈 생성 윈도우• C:Windowssystem32 폴더로 test.dll 파일을 복사합니다.• >>> from ctypes import * >>> libtest = cdll.LoadLibrary(test.dll) >>> print libtest.multiply(2, 2)
  22. 22. ctypes• 사용자 정의 라이브러리 연동하기- 윈도우/리눅스에서 모듈 생성 리눅스• dynamic library로 만듭니다. gcc -shared libtest.o -o libtest.so• 터미널에서 python을 실행하고 libtest.so를 사용합니다.• >>> from ctypes import * >>> import os >>> libtest = cdll.LoadLibrary(os.getcwd() + /libtest.so) >>> print libtest.multiply(2, 2)[출처] : http://blog.naver.com/timberx?Redirect=Log&logNo=30109263914
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×