사용자 도구

사이트 도구


kb:pythoncppbinding

Python C++ Binding

C++에서 Python 인터프리터 사용하기 / Python에서 C++ 코드 사용하기

C 확장 모듈

C 소스로 된 함수를 파이썬에서 사용하기

cm.c
#include <Python.h> 
 
static PyObject* ErrorObject; 
 
static int is_prime(int n) 
{ 
   int k, limit; 
   if (n == 2) return 1; 
   if (n == 1 || n % 2 == 0) return 0; 
 
   limit = n / 2; 
   for (k = 3; k <= limit; k += 2) 
       if (n % k == 0) 
           return 0; 
   return 1; 
} 
 
static PyObject* isprime(PyObject* self, PyObject* args) 
{ 
   int n = 0; 
   if (!PyArg_ParseTuple(args, "i", &n)) 
       return NULL; 
   return Py_BuildValue("i", is_prime(n)); 
} 
 
static struct PyMethodDef methods[] = { 
   {"isprime", isprime, METH_VARARGS}, 
   {NULL, NULL} 
}; 
 
void initcm() 
{ 
   PyObject* m; 
   m = Py_InitModule("cm", methods); 
   ErrorObject = Py_BuildValue("s", "cm error"); 
} 
setup.py
from distutils.core import setup, Extension 
 
setup(name="excel96", 
version="1.0", 
description="advanced python programming report", 
author="Seong-Min Kim", 
author_email="excel96@somewhereonthe.net",
url="http://serious-code.net", 
ext_modules=[Extension("cm", ["cm.c"])]) 

C 확장형

C 소스로 된 객체를 파이썬에서 사용하기

cclass.c
#include "Python.h" 
 
static PyObject* ErrorObject; 
 
#define INDEX_MAX 256 
 
typedef struct { 
   PyObject_HEAD 
   float  values[INDEX_MAX];   
   int    size; 
} cclassobject; 
 
staticforward PyTypeObject cclass; 
 
#define is_cclassobject(v)  ((v)->ob_type == &cclass) 
 
/////////////////////////////////////////////////////////////////////// 
// 개체 함수들 
/////////////////////////////////////////////////////////////////////// 
 
static PyObject* cclass_sum(cclassobject* self, PyObject* args) 
{ 
   float sum = 0.0; 
   int i = 0; 
 
   for (i=0; i<self->size; i++) 
       sum += self->values[i]; 
 
   return Py_BuildValue("f", sum); 
} 
 
static PyObject* cclass_avg(cclassobject* self, PyObject* args) 
{ 
   float sum = 0.0, avg = 0.0; 
   int i = 0; 
 
   for (i=0; i<self->size; i++) 
       sum += self->values[i]; 
 
   avg = sum / ((float)self->size); 
 
   return Py_BuildValue("f", avg); 
} 
 
static PyObject* cclass_str(cclassobject* self) 
{ 
   char repr[1024] = {0, }; 
   char buf[256] = {0, }; 
   int i = 0, j = 0; 
 
   strcat(repr, "("); 
 
   for (i=0; i<self->size; i++) 
   { 
       sprintf(buf, "%.2f", self->values[i]); 
 
       for (j=strlen(buf)-1; j>=0; j--) 
       { 
           if (buf[j] == '0' || buf[j] == '.') buf[j] = 0; 
           else break; 
       } 
 
       strcat(repr, buf); 
       if (i != self->size - 1) strcat(repr, ","); 
   } 
 
   strcat(repr, ")"); 
 
   return Py_BuildValue("s", repr); 
} 
 
static PyObject* cclass_append(cclassobject* self, PyObject* args) 
{ 
   float value = 0.0; 
 
   if (!PyArg_ParseTuple(args, "f", &value)) 
   { 
       PyErr_SetString(ErrorObject, "ParseTuple failed"); 
       return NULL; 
   } 
 
   self->values[self->size] = value; 
   self->size += 1; 
 
   Py_INCREF(Py_None); 
   return Py_None; 
} 
 
static struct PyMethodDef cclass_inst_methods[] = 
{ 
   {"sum", cclass_sum, METH_NOARGS, "sum"}, 
   {"avg", cclass_avg, METH_NOARGS, "avg"}, 
   {"str", cclass_str, METH_NOARGS, "str"}, 
   {"append", cclass_append, METH_VARARGS, "append"}, 
 
   {NULL, NULL, 0, NULL} 
}; 
 
 
 
/////////////////////////////////////////////////////////////////////// 
// 연산자 정의 
/////////////////////////////////////////////////////////////////////// 
 
static cclassobject* newcclassobject(const float* values, int len) 
{ 
   cclassobject *self = PyObject_NEW(cclassobject, &cclass); 
   if (self == NULL) return NULL; 
 
   memcpy(self->values, values, sizeof(float)*len); 
   self->size = len; 
   return self; 
} 
 
static void cclass_dealloc(cclassobject* self) 
{ 
   PyObject_Del(self); 
} 
 
static PyObject* cclass_getattr(cclassobject* self, char* name) 
{ 
   return Py_FindMethod(cclass_inst_methods, (PyObject *)self, name); 
} 
 
static int cclass_length(cclassobject* self) 
{ 
   return self->size; 
} 
 
static PyObject* cclass_getitem(cclassobject* self, int index) 
{   
   if (index < 0 || index >= self->size) 
   { 
       PyErr_SetString(PyExc_IndexError, "index out-of-bounds"); 
       return NULL; 
   } 
 
   return Py_BuildValue("d", self->values[index]); 
} 
 
static PyObject* cclass_repr(cclassobject* self) 
{ 
   char repr[1024] = {0, }; 
   char buf[256] = {0, }; 
   int i = 0, j = 0; 
 
   strcat(repr, "["); 
 
   for (i=0; i<self->size; i++) 
   { 
       sprintf(buf, "%.2f", self->values[i]); 
 
       for (j=strlen(buf)-1; j>=0; j--) 
       { 
           if (buf[j] == '0' || buf[j] == '.') buf[j] = 0; 
           else break; 
       } 
 
       strcat(repr, buf); 
       if (i != self->size - 1) strcat(repr, ", "); 
   } 
 
   strcat(repr, "]"); 
 
   return Py_BuildValue("s", repr); 
} 
 
 
/////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////// 
 
static PySequenceMethods cclass_sequence = 
{ 
   (inquiry)           cclass_length,   /* len(x)   */ 
   (binaryfunc)        0,               /* x + y    */ 
   (intargfunc)        0,               /* x * n    */ 
   (intargfunc)        cclass_getitem,  /* x[i], in */ 
   (intintargfunc)     0,               /* x[i:j]   */ 
   (intobjargproc)     0,               /* x[i] = v */ 
   (intintobjargproc)  0,               /* x[i:j]=v */ 
   (objobjproc)        0,               /* in */ 
   (binaryfunc)        0, 
   (intargfunc)        0 
}; 
 
static PyTypeObject cclass = 
{       
     // 타입 헤더 
     PyObject_HEAD_INIT(NULL)      
     0,                               /* ob_size */ 
     "SampleClass",                   /* tp_name */ 
     sizeof(cclassobject),            /* tp_basicsize */ 
     0,                               /* tp_itemsize */ 
 
     // 표준 메써드들 
     (destructor)   cclass_dealloc, /* tp_dealloc */ 
     (printfunc)    0,              /* tp_print */ 
     (getattrfunc)  cclass_getattr, /* tp_getattr */ 
     (setattrfunc)  0,              /* tp_setattr */ 
     (cmpfunc)      0,              /* tp_compare */ 
     (reprfunc)     cclass_repr,    /* tp_repr */ 
 
     // 자료형 종류 
     0,                             /* 수치형 메써드들 */ 
     &cclass_sequence,              /* 시퀀스형 메써드들 */ 
     0,                             /* 매핑형 메써드들 */ 
 
     (hashfunc)   0,                /* tp_hash */ 
     (binaryfunc) 0,                /* tp_call */ 
     (reprfunc)   0,                /* tp_str  */ 
}; 
 
 
/////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////// 
 
static PyObject* cclass_new(PyObject *self, PyObject *args) 
{ 
   PyObject* listobj = NULL; 
   PyObject* item = NULL; 
 
   int i = 0, len = 0; 
   float values[INDEX_MAX]; 
   float value = 0.0; 
 
   if (!PyArg_ParseTuple(args, "O", &listobj)) 
   { 
       PyErr_SetString(ErrorObject, "ParseTuple failed"); 
       return NULL; 
   } 
 
   if (!PyList_Check(listobj)) 
   { 
       PyErr_SetString(ErrorObject, "list required"); 
       return NULL; 
   } 
 
   len = PyList_Size(listobj); 
   for (i=0; i<len; i++) 
   { 
       item = PyList_GetItem(listobj, i); 
       if (PyFloat_Check(item)) 
       { 
           values[i] = PyFloat_AsDouble(item); 
       } 
       else if (PyInt_Check(item)) 
       { 
           values[i] = PyInt_AsLong(item); 
       } 
   } 
 
   return (PyObject *)newcclassobject(values, len); 
} 
 
static struct PyMethodDef cclass_methods[] = 
{ 
   {"SampleClass", cclass_new, METH_VARARGS, "Create new SampleClass object"}, 
 
   {NULL, NULL, 0, NULL}               
}; 
 
void initcclass(void) 
{ 
   PyObject *m, *d; 
   cclass.ob_type = &PyType_Type; 
   m = Py_InitModule("cclass", cclass_methods); 
 
   d = PyModule_GetDict(m); 
   ErrorObject = Py_BuildValue("s", "cclass error"); 
   PyDict_SetItemString(d, "error", ErrorObject); 
 
   if (PyErr_Occurred()) 
       Py_FatalError("can't initialize module cclass"); 
} 
setup.py
#!/usr/bin/env python 
 
from distutils.core import setup, Extension 
 
setup(name="cclass", 
    version="1.0", 
    description="simple class example - cclass", 
    author="Gang Seong Lee", 
    author_email="excel96@somewhereonthe.net", 
    url="http://serious-code.net/", 
    ext_modules=[Extension("cclass", ["cclass.c"])] 
    ) 

링크

  • PyInline
    파이썬 코드 내에서 다른 언어의 코드를 바로 사용할 수 있도록 해주는 모듈
  • Pyrex
    Pyrex lets you write code that mixes Python and C data types any way you want, and compiles it into a C extension for Python.

kb/pythoncppbinding.txt · 마지막으로 수정됨: 2014/11/11 14:55 저자 excel96