1. 개요
Python은 C 언어로 구현된 언어로, Python 코드에서 C 언어를 활용할 수 있다. 주로 두 가지 방식으로 C와 상호작용하며, 이를 통해 성능을 크게 향상시킬 수 있다.
- C 라이브러리 호출
- ctypes 라이브러리를 사용한다.
- Python 환경에서 직접 C 코드 실행
- C 확장 모듈 또는 C 확장 형을 사용한다.
이 글에서는 두 가지 방식의 특징과 활용 사례를 살펴보고, 코드 예제를 통해 차이점을 이해한다.
2. ctypes
ctypes는 Python 표준 라이브러리로, 외부 C 라이브러리와 상호작용할 수 있는 기능을 제공한다. 이를 통해 Python 코드에서 직접 C 라이브러리의 함수 호출 및 데이터 구조를 다룰 수 있다.
주요 특징
- 외부 라이브러리 호출
- 동적으로 외부 C 라이브러리를 로드하고, 그 안의 함수를 호출할 수 있다.
- C 함수 호출
- 반환값과 인자를 설정하여 Python에서 직접 C 함수를 호출한다.
- C 구조체 조작
- Python에서 C 구조체와 메모리를 다룰 수 있다.
- 플랫폼 독립적
- 여러 플랫폼에서 동일한 코드로 동작한다.
사용 사례
- 외부 라이브러리(시스템, 그래픽, 하드웨어 제어 등)의 기능 호출
- Python에서 C 라이브러리를 래핑하여 활용
예시 코드
import ctypes
# 라이브러리 로드
my_lib = ctypes.CDLL('/path/to/my_lib.so')
# C 함수 호출
result = my_lib.my_function(42, 3.14)
# C 구조체 정의
class MyStruct(ctypes.Structure):
_fields_ = [
("field1", ctypes.c_int),
("field2", ctypes.c_float)
]
# 구조체 생성 및 조작
instance = MyStruct()
instance.field1 = 10
instance.field2 = 3.14
3. C 확장 모듈과 C 확장 형
Python에서 C 코드를 사용하기 위해 두 가지 주요 방법이 존재한다.
- C 확장 모듈
- C 확장 형
3.1 C 확장 모듈 (C Extension Module)
C 언어로 작성된 Python 모듈로, Python의 C API를 사용해 구현된다. C로 작성된 코드는 컴파일된 후 Python 인터프리터에서 로드되며, 새로운 함수와 기능을 Python에 추가한다.
특징
- Python의 내부 기능 확장
- 외부 C 라이브러리 사용 가능
- 플랫폼에 따라 .so 또는 .pyd 파일로 생성
예시코드
C 코드:
#include <Python.h>
// C 함수 정의
static PyObject* my_function(PyObject* self, PyObject* args) {
const char* input;
if (!PyArg_ParseTuple(args, "s", &input)) {
return NULL;
}
printf("C 함수 호출: %s\n", input);
Py_RETURN_NONE;
}
// 함수 목록
static PyMethodDef MyMethods[] = {
{"my_function", my_function, METH_VARARGS, "C 함수 예시"},
{NULL, NULL, 0, NULL}
};
// 모듈 정의
static struct PyModuleDef mymodule = {
PyModuleDef_HEAD_INIT,
"example",
NULL,
-1,
MyMethods
};
// 모듈 초기화
PyMODINIT_FUNC PyInit_example(void) {
return PyModule_Create(&mymodule);
}
Python 코드:
import example
example.my_function("안녕하세요, C 확장 모듈!")
3.2 C 확장 형 (C Extension Type)
C 언어로 Python 객체를 확장하거나 새로운 사용자 정의 데이터 형식을 생성하는 방법이다. PyTypeObject 구조체를 사용해 C 확장 형을 정의하며, 효율적인 데이터 구조 구현에 적합하다.
예시 코드
C 코드:
#include <Python.h>
typedef struct {
PyObject_HEAD
int value;
} MyObject;
static int MyObject_init(MyObject* self, PyObject* args, PyObject* kwds) {
self->value = 0;
return 0;
}
static PyObject* MyObject_set_value(MyObject* self, PyObject* args) {
int value;
if (!PyArg_ParseTuple(args, "i", &value)) {
return NULL;
}
self->value = value;
Py_RETURN_NONE;
}
static PyMethodDef MyObject_methods[] = {
{"set_value", (PyCFunction)MyObject_set_value, METH_VARARGS, "값 설정"},
{NULL, NULL, 0, NULL}
};
static PyTypeObject MyObjectType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.MyObject",
.tp_basicsize = sizeof(MyObject),
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_init = (initproc)MyObject_init,
.tp_methods = MyObject_methods,
};
PyMODINIT_FUNC PyInit_example(void) {
PyObject* m;
if (PyType_Ready(&MyObjectType) < 0) {
return NULL;
}
m = PyModule_Create(&examplemodule);
if (m == NULL) {
return NULL;
}
Py_INCREF(&MyObjectType);
PyModule_AddObject(m, "MyObject", (PyObject*)&MyObjectType);
return m;
}
Python 코드:
import example
obj = example.MyObject()
obj.set_value(42)
print(f"설정된 값: {obj.value}")
3.3 C 확장 모듈과 C 확장 형의 차이점
구분 | C 확장 모듈 | C 확장 형 |
용도 | Python에 새로운 함수와 기능 추가 | Python 데이터 형식을 확장 |
기술적 차이 | C 함수 호출을 Python에서 가능 | Python 객체 구조를 C 레벨에서 조작 |
사용 사례 | 새로운 함수 생성 및 성능 최적화 | 효율적인 데이터 구조 구현 |
4. 결론
Python과 C의 결합은 성능 향상과 확장 가능성을 동시에 제공한다. ctypes는 간단한 방식으로 외부 C 라이브러리를 활용할 수 있는 반면, C 확장 모듈과 C 확장 형은 보다 깊이 있는 통합을 통해 Python 환경에서 C 코드를 최대한 활용할 수 있게 한다. 상황에 따라 적합한 방식을 선택해 Python 코드의 성능을 극대화할 수 있다.
'기술 노트' 카테고리의 다른 글
이진탐색(Binary Search) 완벽 가이드 (1) | 2025.01.05 |
---|---|
Shunting Yard 알고리즘: 중위 표기법에서 후위 표기법으로 (1) | 2025.01.04 |
CHM(Compiled HTML Help, 윈도우 도움말 파일) (0) | 2024.10.24 |
MacOS 개발 첫 발: 환경 설정부터 코드 호출까지 (0) | 2022.03.18 |
Unix와 Linux: 다양한 OS 환경에서의 빌드와 자동화 경험 (0) | 2022.03.17 |