¾ÕÀ¸·Î    ¸ñÂ÷    1    2    3    4    Á¦5Àå    6    7    8    ´ÙÀ½À¸·Î

5. ÆÄÀ̽ã È®ÀåÇϱâ

5.1. C·Î Á÷Á¢ ÇÔ¼ö¸¦ ÀÛ¼ºÇÒ ¼ö ÀÖ³ª¿ä?

³×, ³»Àå ¸ðµâÀ» ¸¸µé ¼ö ÀÖ½À´Ï´Ù. ÇÔ¼ö, º¯¼ö, ¿¹¿Ü ±×¸®°í ½ÉÁö¾î´Â »õ·Î¿î ÇüÀ» C·Î ³»Àå ¸ðµâ¿¡ ´ãÀ» ¼ö ÀÖ½À´Ï´Ù. ÀÌ°ÍÀº ¹®¼­ "ÆÄÀ̽ã ÀÎÅÍÇÁ¸®Å͸¦ ³»ÀåÇÏ°í È®ÀåÇϱâ (Extending and Embedding the Python Interpreter)"¿¡ ¼³¸íµÇ¾î ÀÖ½À´Ï´Ù. ¶Ç µ¿Àû ÀûÀç¿¡ °üÇÑ Àåµµ ÀÐ¾î º¸¼¼¿ä.

ÀÌ°Í¿¡ ´ëÇÑ ´õ ¸¹Àº Á¤º¸´Â ÆÄÀ̽㿡 °üÇÑ Ã¥µé¿¡ ÀÖ½À´Ï´Ù: ÇÁ·Î±×·¡¹Ö ÆÄÀ̽ã, ÆÄÀ̽ãÀ¸·Î ÀÎÅÍ³Ý ÇÁ·Î±×·¡¹ÖÇϱâ(Programming Python, Internet Programming with Python), ±×¸®°í ÆÄÀ̽ã-Ã¥(Das Python-Buch) (µ¶ÀϾî).


5.2. C++·Î Á÷Á¢ ÇÔ¼ö¸¦ ÀÛ¼ºÇÒ ¼ö ÀÖ³ª¿ä?

±×·¸½À´Ï´Ù, C++¿¡¼­ ¹ß°ßµÇ´Â C-ȣȯ¼ºÀ» »ç¿ëÇؼ­¿ä. ±âº»ÀûÀ¸·Î extern "C" { ... }¸¦ ÆÄÀ̽ãÀÇ include ÆÄÀÏÀÇ ÁÖÀ§¿¡ µÑ·¯½Î°í extern "C" ¸¦ °¢ ÇÔ¼ö ¾Õ¿¡ ¹èÄ¡Çϸé ÆÄÀ̽ã ÀÎÅÍÇÁ¸®ÅÍ¿¡ ÀÇÇؼ­ È£ÃâµÉ °ÍÀÔ´Ï´Ù. Àü¿ª ȤÀº C++ °´Ã¼¸¦ ±¸¼ºÀÚ¿Í ÇÔ²² »ç¿ëÇÏ´Â °ÍÀº º°·Î ÁÁÀº »ý°¢ÀÌ ¾Æ´Õ´Ï´Ù.


5.3. ÀÓÀÇÀÇ ÆÄÀ̽㠼­¼ú¹®À» C·ÎºÎÅÍ ¾î¶»°Ô ½ÇÇàÇÒ ¼ö ÀÖ³ª¿ä?

ÀÌ·¸°Ô Çϱâ À§ÇÑ ÃÖ°í-¼öÁØÀÇ ÇÔ¼ö´Â PyRun_SimpleString()·Î¼­ ÇÑ°³ÀÇ ¹®ÀÚ¿­ Àμö¸¦ ÃëÇϴµ¥ __main__ ¸ðµâÀÇ ¹®¸Æ¿¡¼­ ½ÇÇàµÇ¾î (±¸¹®¿¡·¯¸¦ Æ÷ÇÔÇÏ¿©) ¿¹¿Ü°¡ ÀϾ¸é -1À» ¼º°øÇϸé 0À» ¹ÝȯÇÕ´Ï´Ù. ´õ Á¦¾î¸¦ ÇÏ°í ½ÍÀ¸¸é, PyRun_String()À» »ç¿ëÇϼ¼¿ä; Python/pythonrun.c¿¡ ÀÖ´Â PyRun_SimpleString()À» ÂüÁ¶Çϼ¼¿ä.


5.4. ÀÓÀÇÀÇ ÆÄÀ̽ã Ç¥Çö½ÄÀ» ¾î¶»°Ô C·ÎºÎÅÍ Æò°¡ÇÒ ¼ö ÀÖ³ª¿ä?

ÀÌÀü Áú¹®¿¡ ÀÖ¾ú´ø ÇÔ¼ö PyRun_String()À» ½ÃÀÛ ½Éº¼ eval_inputÀ» °¡Áö°í È£ÃâÇϼ¼¿ä ( 1.5a1¿¡¼­´Â Py_eval_inputÀ¸·Î ½ÃÀÛÇÕ´Ï´Ù); ±×°ÍÀº Ç¥Çö½ÄÀ» Çؼ®Çؼ­, Æò°¡ÇÏ°í, ±×¸®°í ±× °ªÀ» ¹ÝȯÇÕ´Ï´Ù.


5.5. ¾î¶»°Ô ÆÄÀ̽㠰´Ã¼·ÎºÎÅÍ C °ªÀ» ÃßÃâÇϳª¿ä?

±×°ÍÀº ±× °´Ã¼ÀÇ Çü¿¡ µû¶ó ´Ù¸¨´Ï´Ù. ÅÍÇÃÀ̶ó¸é, PyTupleSize(o)´Â ±æÀ̸¦ ¹ÝȯÇÏ°í PyTuple_GetItem(o, i)´Â i¹ø°ÀÇ Ç׸ñÀ» ¹ÝȯÇÕ´Ï´Ù; ¸®½ºÆ®ÀÇ PyListSize(o)¿Í PyList_GetItem(o, i)µµ ºñ½ÁÇÕ´Ï´Ù. ¹®ÀÚ¿­¿¡ °üÇؼ­´Â, PyString_Size(o) ±× ±æÀ̸¦, PyString_AsString(o)´Â ±× °ª¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ ¹ÝȯÇÕ´Ï´Ù (ÁÖ¸ñÇÒ °ÍÀº ÆÄÀ̽㠹®ÀÚ¿­Àº null ¹ÙÀÌÆ®¸¦ Æ÷ÇÔÇÒ ¼ö À־ strlen()Àº ¾ÈÀüÇÏÁö ¾Ê½À´Ï´Ù). °´Ã¼°¡ ¾î¶² ÇüÀÎÁö Å×½ºÆ®Çغ¸±â À§Çؼ­´Â, ¸ÕÀú ±×°ÍÀÌ NULLÀÌ ¾Æ´Ï¶ó´Â °ÍÀ» È®ÀÎÇϼ¼¿ä, ±×¸®°í ³ª¼­ PyString_Check(o), PyTuple_Check(o), PyList_Check(o), µîµîÀ» »ç¿ëÇϼ¼¿ä.

¶ÇÇÑ ÆÄÀ̽㠰´Ã¼¿¡ ´ëÇÑ °í-¼öÁØ APIµµ Àִµ¥ À̸¥¹Ù 'Ãß»óÀû(abstract)' ÀÎÅÍÆäÀ̽º¿¡ ÀÇÇÏ¿© Á¦°øµË´Ï´Ù -- ´õ ÀÚ¼¼ÇÑ »çÇ×Àº Include/abstract.h¸¦ ÀÐ¾î º¸¼¼¿ä. ¿¹¸¦ µé¾î ±×°ÍÀº (PySequence_Length(), PySequence_GetItem(), µîµî°ú °°Àº È£ÃâÀ» »ç¿ëÇÏ¿©) ¾î¶°ÇÑ ÆÄÀ̽㠿¬¼Ó¿­(¿¹. ¸®½ºÆ®¿Í ÅÍÇÃ)°úÀÇ Á¢¼Óµµ Çã¿ëÇÒ »Ó¸¸ ¾Æ´Ï¶ó ´Ù¸¥ ¸¹Àº À¯¿ëÇÑ ÇÁ·ÎÅäÄÝ°úÀÇ Á¢¼ÓÀ» Çã¿ëÇÕ´Ï´Ù.


5.6. Py_BuildValue()¸¦ »ç¿ëÇÏ¿© ¾î¶»°Ô ÀÓÀÇÀÇ ±æÀ̸¦ °¡Áø ÅÍÇÃÀ» »ý¼ºÇϳª¿ä?

±×·²¼ö ¾ø½À´Ï´Ù. ´ë½Å¿¡ t = PyTuple_New(n)¸¦ »ç¿ëÇϼ¼¿ä, ±×¸®°í ±×°ÍÀ» PyTuple_SetItem(t, i, o)À» »ç¿ëÇÏ´Â °´Ã¼·Î ä¿ì¼¼¿ä -- note that this "eats" a reference count of o. ¸®½ºÆ®ÀÇ PyList_New(n)¿Í PyList_SetItem(l, i, o)¿¡µµ ºñ½ÁÇÏ°Ô Àû¿ëµË´Ï´Ù . ÁÖÀÇÇÒ °ÍÀº ¹Ýµå½Ã ¸ðµç ÅÍÇà Ç׸ñÀ» ±× ÅÍÇÃÀ» ÆÄÀ̽ã Äڵ忡 °Ç³×±â Àü¿¡ ¾î¶² °ªÀ¸·Î ¼³Á¤ÇØ¾ß ÇÑ´Ù´Â °ÍÀÔ´Ï´Ù. -- PyTuple_New(n)´Â ±×°ÍµéÀ» NULL·Î ÃʱâÈ­ Çϴµ¥, ±× °ªÀº À¯È¿ÇÑ ÆÄÀ̽㠰ªÀÌ ¾Æ´Õ´Ï´Ù.


5.7. °´Ã¼ÀÇ ¸Þ½îµå¸¦ C·ÎºÎÅÍ ¾î¶»°Ô È£ÃâÇϳª¿ä?

ÇÑ °´Ã¼ÀÇ ÀÓÀÇÀûÀÎ ¸Þ½îµå¸¦ È£ÃâÇϴµ¥¿¡´Â PyObject_CallMethod() ÇÔ¼ö°¡ »ç¿ëµÉ ¼ö ÀÖ½À´Ï´Ù. ¸Å°³º¯¼öµéÀº ±× °´Ã¼¿Í, È£ÃâµÉ ¸Þ½îµåÀÇ À̸§, Py_BuildValue()¿Í »ç¿ëµÇ´Â °Í°ú °°Àº Çü½ÄÈ­ ¹®ÀÚ¿­ µîµîÀÔ´Ï´Ù, ±×¸®°í ±× Àμö °ªµéÀº:

    PyObject *
    PyObject_CallMethod(PyObject *object, char *method_name,
                        char *arg_format, ...);
ÀÌ°ÍÀº -- ³»ÀåÀ̵ç ȤÀº »ç¿ëÀÚ-Á¤ÀÇÀÌµç ¸Þ½îµå¸¦ °¡Áö°í ÀÖ´Â ¸ðµç °´Ã¼¿¡ ÀÛµ¿ÇÕ´Ï´Ù. ±× ¹Ýȯ°ªÀÇ ÂüÁ¶È½¼ö¸¦ °¨¼Ò½ÃÅ°´Â(DECREF'ing) °ÍÀº °á±¹ ¿©·¯ºÐÀÇ Ã¥ÀÓÀÔ´Ï´Ù.

¿¹¸¦ µé¾î ÇÑ ÆÄÀÏ °´Ã¼ÀÇ "seek" ¸Þ½îµå¸¦ Àμö 10, 0 À» °¡Áö°í È£ÃâÇÏ·Á¸é (±× ÆÄÀÏ °´Ã¼ÀÇ Æ÷ÀÎÅÍ°¡ "f"¶ó´Â °¡Á¤ÇÏ¿¡):

        res = PyObject_CallMethod(f, "seek", "(ii)", 10, 0);
        if (res == NULL) {
                ... an exception occurred ...
        }
        else {
                DECREF(res);
        }
ÁÖ¸ñÇÒ °ÍÀº PyObject_CallObject()°¡ Ç×»ó ±× Àμö ¸ñ·Ï¿¡ ´ëÇÏ¿© ÅÍÇÃÀ» ¿øÇϹǷÎ, ÇÔ¼ö¸¦ Àμö¾øÀÌ È£ÃâÇÏ·Á¸é, ±× Çü½Ä¿¡ "()"¸¦ °Ç³× ÁÖ¼¼¿ä, ±×¸®°í ÇÔ¼ö¸¦ ÇϳªÀÇ Àμö·Î È£ÃâÇÏ·Á¸é, ±× Àμö¸¦ °ýÈ£·Î µÑ·¯½Î¼¼¿ä, ´ÙÀ½°ú °°ÀÌ "(i)".


5.8. PyErr_Print()°¡ ³»´Â Ãâ·ÂÀ» ¾î¶»°Ô ³ªÆ÷Çϳª¿ä (ȤÀº stdout/stderr¿¡ Ãâ·ÂµÇ´Â ¸ðµç °Í)?

(¸¶Å© ÇظóµåÀÇ (Mark Hammond)ÀÇ ¹è·Á):

ÆÄÀ̽ã Äڵ忡¼­´Â, "write()" ¸Þ½îµå¸¦ Áö¿øÇÏ´Â °´Ã¼¸¦ ¼±¾ðÇϼ¼¿ä. sys.stdout¿Í sys.stderr¸¦ ÀÌ °´Ã¼¿¡ ¹æÇâÀüȯÇϼ¼¿ä. print_error¸¦ È£ÃâÇϰųª, ȤÀº ´Ü¼øÈ÷ Ç¥ÁØ ¿ªÃßÀû ¸ÞÄ«´ÏÁòÀÌ ÀÛµ¿Çϵµ·Ï Çã¿ëÇϼ¼¿ä. ±×·¯¸é, ±× Ãâ·ÂÀº ¿©·¯ºÐÀÇ write() ¸Þ½îµå°¡ ±×°ÍÀ» º¸³»´Â °÷¿¡ Ãâ·ÂµÉ °ÍÀÔ´Ï´Ù.

ÀÌ·¸°Ô ÇÏ´Â °¡Àå ½¬¿î ¹æ¹ýÀº Ç¥ÁØ ¶óÀ̺귯¸®¿¡ ÀÖ´Â StringIO Ŭ·¡½º¸¦ »ç¿ëÇÏ´Â °ÍÀÔ´Ï´Ù.

Ç¥ÁØ Ãâ·ÂÀ» ³ªÆ÷Çϱâ À§ÇÑ ¿¹Á¦ ÄÚµå¿Í »ç¿ë¹ý:

	>>> class StdoutCatcher:
	...  def __init__(self):
	...   self.data = ''
	...  def write(self, stuff):
	...   self.data = self.data + stuff
	...
	>>> import sys
	>>> sys.stdout = StdoutCatcher()
	>>> print 'foo'
	>>> print 'hello world!'
	>>> sys.stderr.write(sys.stdout.data)
	foo
	hello world!


5.9. ÆÄÀ̽ãÀ¸·Î ÀÛµ¿µÈ ¸ðµâ¿¡ C¿¡¼­ ¾î¶»°Ô Á¢±ÙÇϳª¿ä?

±× ¸ðµâ °´Ã¼¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ ´ÙÀ½°ú °°ÀÌ ¾òÀ» ¼ö ÀÖ½À´Ï´Ù:

        module = PyImport_ImportModule("<modulename>");
¸¸¾à ±× ¸ðµâÀÌ ¾ÆÁ÷ ¼öÀÔµÇÁö ¾Ê¾Ò´Ù¸é (Áï. sys.modules¿¡ ¾ÆÁ÷ Á¸ÀçÇÏÁö ¾Ê´Â´Ù¸é), ÀÌ°ÍÀº ±× ¸ðµâÀ» ÃʱâÈ­ÇÕ´Ï´Ù; ±×·¸Áö ¾ÊÀ¸¸é ´Ü¼øÈ÷ sys.modules["<modulename>"]ÀÇ ±× °ªÀ» ¹ÝȯÇÕ´Ï´Ù. ÁÖ¸ñÇÒ °ÍÀº ±× ¸ðµâÀ» ¾î¶°ÇÑ À̸§°ø°£¿¡µµ Áý¾î ³ÖÁö ¾Ê´Â´Ù´Â °ÍÀÔ´Ï´Ù -- ¿ÀÁ÷ ÃʱâÈ­ µÇ¾ú´ÂÁö ±×¸®°í sys.modules¿¡ ÀúÀåµÇ¾ú´ÂÁö ¸¸À» È®ÀÎÇÕ´Ï´Ù.

±×·¯¸é ±× ¸ðµâÀÇ ¼Ó¼º¿¡ (Áï. ±× ¸ðµâ¿¡ Á¤ÀÇµÈ ¾î¶² À̸§¿¡µµ) ´ÙÀ½°ú °°ÀÌ Á¢±ÙÇÒ ¼ö ÀÖ½À´Ï´Ù:

        attr = PyObject_GetAttrString(module, "<attrname>");
º¯¼öµéÀ» ±× ¸ðµâ¿¡ ÇÒ´çÇϱâ À§ÇÏ¿©, PyObject_SetAttrString()À» È£ÃâÇÏ´Â °Í ¶ÇÇÑ ÀÛµ¿ÇÕ´Ï´Ù.


5.10. ¾î¶»°Ô ÆÄÀ̽ãÀ¸·ÎºÎÅÍ C++ °´Ã¼¿¡ Á¢¼ÓÇϳª¿ä?

ÇÊ¿ä¿¡ µû¶ó, ¸¹Àº Á¢±Ù¹æ¹ýÀÌ ÀÖ½À´Ï´Ù. ¼öµ¿À¸·Î ÀÌ·¸°Ô Çϱâ À§Çؼ­´Â, "Extending and Embedding" ¹®¼­¸¦ ÀÐÀ½À¸·Î¼­ ½ÃÀÛÇϼ¼¿ä (Doc/ext.tex, ¶Ç ´ÙÀ½ ÂüÁ¶ http://www.python.org/doc/). ¾Ë¼ö ÀÖ´Â °ÍÀº ÆÄÀ̽ãÀÇ ½ÇÇà-½Ã°£ ½Ã½ºÅÛ¿¡ ´ëÇÏ¿©, C¿Í C++ÀÇ »çÀÌ¿¡´Â ÀüÀûÀ¸·Î ¸¹Àº Â÷ÀÌ°¡ ÀÖÁö´Â ¾Ê´Ù´Â °ÍÀÔ´Ï´Ù -- ±×·¡¼­ CÀÇ ±¸Á¶(Æ÷ÀÎÅÍ) Çü¿¡¼­ »õ·Î¿î ÆÄÀ̽ã ÇüÀ» ±¸ÃàÇϱâ À§ÇÑ Àü·«Àº C++ °´Ã¼¿¡µµ ÀÛµ¿ÇÒ °ÍÀÔ´Ï´Ù.

À¯¿ëÇÑ ÀÚµ¿È­µÈ Á¢±Ù¹ýÀº SWIGÀÔ´Ï´Ù (C¿¡µµ ÀÛµ¿ÇÕ´Ï´Ù): http://www.swig.org//.


5.11. mSQLmoduleÀÌ (ȤÀº ±¸Çü ¸ðµâÀÌ) ÆÄÀ̽ã 1.5 (ȤÀº ±×ÀÌ»ó)À¸·Î ±¸ÃàµÇÁö ¾Ê½À´Ï´Ù.

ÆÄÀ̽ã 1.4 ÀÌÈÄ·Î "Python.h"°¡ È®Àå¸ðµâ¿¡¼­ ÇÊ¿äÇÑ include ÆÄÀÏÀ» °¡Áú °ÍÀÔ´Ï´Ù. ÇÏÀ§ ȣȯ¼ºÀº ¹öÀü 1.4ÀÌÈÄ·Î ¶³¾îÁý´Ï´Ù. ±×·¡¼­ mSQLmodule.c Àº "allobjects.h"¸¦ ¹ß°ßÇÒ ¼ö ¾øÀ¸¹Ç·Î ±¸ÃàµÇÁö ¾ÊÀ» °ÍÀÔ´Ï´Ù. mSQLmodule.c¿¡¼­ÀÇ ´ÙÀ½ÀÇ º¯°æÀº 1.4¹öÀüÀ¸·Î ±¸ÃàÇÒ ¶§´Â ¹«ÇØÇÏ¸ç ±×¸®°í ÀÌÈÄÀÇ ÆÄÀ̽㠹öÀü¿¡¼­ ±×·¸°Ô ÇÏ·Á¸é ÇʼöÀûÀÔ´Ï´Ù:

´ÙÀ½ ¶óÀÎÀ» Áö¿ì°í:

	#include "allobjects.h"
	#include "modsupport.h"
´ë½Å¿¡ ´ÙÀ½À» »ðÀÔÇϼ¼¿ä:

	#include "Python.h"
´ÙÀ½°ú °°ÀÌ Ãß°¡ÇÒ ÇÊ¿äµµ ÀÖ½À´Ï´Ù.

                #include "rename2.h"
¸¸¾à ±× ¸ðµâÀÌ "old names"À» »ç¿ëÇϸé.

ÀÌ°ÍÀº ´Ù¸¥ ¿À·¡µÈ ÆÄÀ̽㠸ðµâ¿¡µµ ÀϾ ¼ö Àִµ¥, °°Àº ÇØ°áÃ¥ÀÌ Àû¿ëµË´Ï´Ù.


5.12. ¼³Á¤ ÆÄÀÏÀ» »ç¿ëÇÏ¿© ¸ðµâÀ» Ãß°¡ÇÏ¿´½À´Ï´Ù ±×·±µ¥ make °¡ ½ÇÆÐÇÕ´Ï´Ù! ¾îÂîµÈ ÀÏÀÌÁö¿ä?

¼³Á¤Àº newlineÀ¸·Î ³¡³ª¾ß Çϴµ¥, ¸¸¾à newlineÀÌ ¾ø´Ù¸é ½½ÇÄÀ» ¸Âº¾´Ï´Ù. ÀÌ °¡´É¼ºÀ» Á¦Ãĵΰí, ¾Æ¸¶µµ ´Ù¸¥ ºñ-ÆÄÀ̽ã-Á¾¼ÓÀûÀÎ ¿¬°á ¹®Á¦¸¦ °¡Áö°í ÀÖÀ» ¼öµµ ÀÖ½À´Ï´Ù.


5.13. ÆÄÀ̽㠸ðµâÀ» ·¹µåÇØÆ® ¸®´ª½º ½Ã½ºÅÛ¿¡¼­ ÄÄÆÄÀÏÇÏ·Á°í ÇÕ´Ï´Ù, ±×·¯³ª ¾î¶² ÆÄÀϵéÀÌ ºÐ½ÇµÇ¾î ¾ø½À´Ï´Ù.

ÆÄÀ̽ãÀ» À§ÇÑ, ·¹µå ÇØÆ®ÀÇ RPMÀº /usr/lib/python1.x/config/ µð·ºÅ丮¸¦ Æ÷ÇÔÇÏ°í ÀÖÁö ¾ÊÀºµ¥, ±× µð·ºÅ丮´Â ÆÄÀ̽ã È®ÀåÀ» ÄÄÆÄÀÏÇϴµ¥ ÇÊ¿äÇÑ ´Ù¾çÇÑ ÆÄÀϵéÀ» ´ã°í ÀÖ½À´Ï´Ù. ÆÄÀ̽ã-°³¹ß(python-devel) RPMÀ» ¼³Ä¡Çϼż­ ÇÊ¿äÇÑ ÆÄÀϵéÀ» ¾òµµ·Ï Çϼ¼¿ä.


5.14. "SystemError: _PyImport_FixupExtension: module yourmodule not loaded" ÀÌ°ÍÀÌ ¹«½¼ ¶æÀΰ¡¿ä?

ÀÌ°ÍÀº "yourmodule"À̶ó´Â À̸§ÀÇ È®Àå ¸ðµâÀ» »ý¼ºÇÏ¿´Áö¸¸, ¸ðµâÀÇ ÃʱâÈ­ ÇÔ¼ö°¡ ±× À̸§À¸·Î ÃʱâÈ­ÇÏÁö ¾Ê´Â´Ù´Â ¶æÀÔ´Ï´Ù.

¸ðµç ¸ðµâÀÇ ÃʱâÈ­ ÇÔ¼ö´Â ´ÙÀ½°ú ºñ½ÁÇÑ ¶óÀÎÀ» °¡Áú °ÍÀÔ´Ï´Ù:

  module = Py_InitModule("yourmodule", yourmodule_functions);
¸¸¾à ÀÌ ÇÔ¼ö¿¡ °Ç³×Áö´Â ¹®ÀÚ¿­ÀÌ ¿©·¯ºÐÀÇ È®Àå ¸ðµâ À̸§°ú °°Áö ¾Ê´Ù¸é, SystemError°¡ ÀϾ °ÍÀÔ´Ï´Ù.


5.15. "¹Ì¿Ï¼º ÀÔ·Â"°ú "¹«È¿ÇÑ ÀÔ·Â"À» ±¸ºÐÇÏ´Â ¹ý?

°¡²û ¿©·¯ºÐÀº ÆÄÀ̽ãÀÇ »óÈ£´ëÈ­ÀûÀÎ ÇàÀ§¸¦ Èä³»³»±â¸¦ ¿øÇϴµ¥, ÀÔ·ÂÀÎ ¹Ì¿Ï¼º À϶§´Â °è¼ÓÀûÀ¸·Î ÇÁ·ÒÇÁÆ®¸¦ º¸¿© ÁÖÁö¸¸ (¿¹¸¦ µé¾î. "if" ¼­¼ú¹®ÀÇ Ã³À½À» ŸÀÚÇϰųª °ýÈ£ ȤÀº »ïÁß ¹®ÀÚ¿­ ÀοëºÎÈ£¸¦ ´ÝÁö ¾ÊÀ» ¶§), ±× ÀÔ·ÂÀÌ ¹«È¿ÇÒ ¶§´Â Áï½Ã ±¸¹® ¿¡·¯ ¸Þ½ÃÁö¸¦ º¸¿©ÁÝ´Ï´Ù.

ÆÄÀ̽㿡¼­´Â codeop ¸ðµâÀ» »ç¿ëÇÒ ¼ö Àִµ¥, Çؼ®±âÀÇ ÇàÀ§¸¦ °ÅÀÇ ±ÙÁ¢ÇÏ°Ô Èä³»³À´Ï´Ù. ¿¹¸¦ µé¾î, IDLEÀº ÀÌ°ÍÀ» »ç¿ëÇÕ´Ï´Ù.

C¿¡¼­ ±×·¸°Ô ÇϱâÀ§ÇÑ °¡Àå ½¬¿î ¹æ¹ýÀº PyRun_InteractiveLoop()¸¦ È£ÃâÇÏ°í (¾Æ¸¶µµ °³º°ÀûÀÎ ¾²·¹µå·Î) ±×¸®°í ÆÄÀ̽ã ÀÎÅÍÇÁ¸®ÅÍ°¡ ±× ÀÔ·ÂÀ» ¿©·¯ºÐÀ» ´ë½ÅÇÏ¿© ó¸®Çϵµ·Ï ³õ¾Æ µÎ´Â °ÍÀÔ´Ï´Ù. ¶ÇÇÑ PyOS_ReadlineFunctionPointer¸¦ ¼³Á¤ÇÏ¿© ÀÚ½ÅÀÌ Àç´ÜÇÑ ÀÔ·Â ÇÔ¼ö¸¦ ÁöÀûÇÒ ¼öµµ ÀÖ½À´Ï´Ù. ´õ ÈùÆ®¸¦ ¿øÇϽøé Modules/readline.c¿Í Parser/myreadline.c¸¦ ÂüÁ¶Çϼ¼¿ä.

±×·¸Áö¸¸ ¶§·Î ³»ÀåµÈ ÆÄÀ̽ã ÀÎÅÍÇÁ¸®Å͸¦ ¿©·¯ºÐÀÇ ³ª¸ÓÁö ¾îÇø®ÄÉÀ̼ǰú °°Àº ¾²·¹µå¿¡¼­ ½ÇÇàÇÒ ÇÊ¿ä°¡ ÀÖÁö¸¸, »ç¿ëÀÚ ÀÔ·ÂÀ» ±â´Ù¸®´Â ÁßÀ̾ PyRun_InteractiveLoop()¸¦ ÁßÁö ½Ãų¼ö ¾ø´Â ¶§°¡ ÀÖ½À´Ï´Ù. ±×·¯¸é ÇϳªÀÇ ÇØ°áÃ¥Àº PyParser_ParseString()¸¦ È£ÃâÇؼ­ e.error°¡ E_EOF¿Í °°ÀºÁö Å×½ºÆ®ÇÏ´Â °ÍÀÔ´Ï´Ù (À̶§ ±× ÀÔ·ÂÀº ¹Ì¿Ï¼ºÀÔ´Ï´Ù). ´ÙÀ½Àº ¾Ë·º½º ÆĹö(Alex Farber)ÀÇ Äڵ忡 ¿µ°¨À» ¹ÞÀº, °ËÁõµÇÁö ¾ÊÀº, ¿¹Á¦ ÄÚµå Á¶°¢ÀÔ´Ï´Ù:

  #include <Python.h>
  #include <node.h>
  #include <errcode.h>
  #include <grammar.h>
  #include <parsetok.h>
  #include <compile.h>
  int testcomplete(char *code)
    /* code should end in \n */
    /* return -1 for error, 0 for incomplete, 1 for complete */
  {
    node *n;
    perrdetail e;
    n = PyParser_ParseString(code, &_PyParser_Grammar,
                             Py_file_input, &e);
    if (n == NULL) {
      if (e.error == E_EOF)
        return 0;
      return -1;
    }
    PyNode_Free(n);
    return 1;
  }
¶Ç ´Ù¸¥ ÇØ°áÃ¥Àº ±× Á¢¼öµÈ ¹®ÀÚ¿­À» Py_CompileString()À¸·Î ÄÄÆÄÀÏ Çغ¸´Â °ÍÀÔ´Ï´Ù. ¸¸¾à Àß ÄÄÆÄÀÏ µÈ´Ù¸é - ±× ¹ÝȯµÈ ÄÚµå °´Ã¼¸¦ PyEval_EvalCode()¸¦ È£ÃâÇÔÀ¸·Î½á ½ÇÇàÇØ º¸¼¼¿ä. ±×·¸Áö ¾ÊÀ¸¸é ³ªÁß¿¡ »ç¿ëÇϱâ À§ÇÏ¿© ±× ÀÔ·ÂÀ» ÀúÀåÇϼ¼¿ä. ¸¸¾à ÄÄÆÄÀÏÀÌ ½ÇÆÐÇϸé, ±×°ÍÀÌ ¿¡·¯ÀÎÁö ȤÀº ´ÜÁö ´õ ÀÔ·ÂÀÌ ÇÊ¿äÇÑ °ÍÀÎÁö ¾Ë¾Æ º¸¼¼¿ä - ±× ¿¹¿Ü ÅÍÇ÷κÎÅÍ ¸Þ½ÃÁö ¹®ÀÚ¿­À» ÃßÃâÇÏ¿© ±×°ÍÀ» "Çؼ®Áß¿¡ ¿¹»ó ¸øÇÑ EOF(unexpected EOF while parsing)"°ú ºñ±³ÇØ º¸½Ã¸é µË´Ï´Ù. ¿©±â¿¡ GNU readline ¶óÀ̺귯¸®¸¦ »ç¿ëÇÑ ¿ÏÀüÇÑ ¿¹Á¦°¡ ÀÖ½À´Ï´Ù. (readline()È£ÃâÇÏ´Â Áß¿¡ SIGINT¸¦ ¹«½ÃÇÏ°í ½ÍÀ» ¼öµµ ÀÖ½À´Ï´Ù):

  #include <stdio.h>
  #include <readline.h>
  #include <Python.h>
  #include <object.h>
  #include <compile.h>
  #include <eval.h>
  int main (int argc, char* argv[])
  {
    int i, j, done = 0;                          /* lengths of line, code */
    char ps1[] = ">>> ";
    char ps2[] = "... ";
    char *prompt = ps1;
    char *msg, *line, *code = NULL;
    PyObject *src, *glb, *loc;
    PyObject *exc, *val, *trb, *obj, *dum;
    Py_Initialize ();
    loc = PyDict_New ();
    glb = PyDict_New ();
    PyDict_SetItemString (glb, "__builtins__", PyEval_GetBuiltins ());
    while (!done)
    {
      line = readline (prompt);
      if (NULL == line)                          /* CTRL-D pressed */
      {
        done = 1;
      }
      else
      {
        i = strlen (line);
        if (i > 0)
          add_history (line);                    /* save non-empty lines */
        if (NULL == code)                        /* nothing in code yet */
          j = 0;
        else
          j = strlen (code);
        code = realloc (code, i + j + 2);
        if (NULL == code)                        /* out of memory */
          exit (1);
        if (0 == j)                              /* code was empty, so */
          code[0] = '\0';                        /* keep strncat happy */
        strncat (code, line, i);                 /* append line to code */
        code[i + j] = '\n';                      /* append '\n' to code */
        code[i + j + 1] = '\0';
        src = Py_CompileString (code, "<stdin>", Py_single_input);
        if (NULL != src)                         /* compiled just fine - */
        {
          if (ps1  == prompt ||                  /* ">>> " or */
              '\n' == code[i + j - 1])           /* "... " and double '\n' */
          {                                               /* so execute it */
            dum = PyEval_EvalCode ((PyCodeObject *)src, glb, loc);
            Py_XDECREF (dum);
            Py_XDECREF (src);
            free (code);
            code = NULL;
            if (PyErr_Occurred ())
              PyErr_Print ();
            prompt = ps1;
          }
        }                                        /* syntax error or E_EOF? */
        else if (PyErr_ExceptionMatches (PyExc_SyntaxError))
        {
          PyErr_Fetch (&exc, &val, &trb);        /* clears exception! */
          if (PyArg_ParseTuple (val, "sO", &msg, &obj) &&
              !strcmp (msg, "unexpected EOF while parsing")) /* E_EOF */
          {
            Py_XDECREF (exc);
            Py_XDECREF (val);
            Py_XDECREF (trb);
            prompt = ps2;
          }
          else                                   /* some other syntax error */
          {
            PyErr_Restore (exc, val, trb);
            PyErr_Print ();
            free (code);
            code = NULL;
            prompt = ps1;
          }
        }
        else                                     /* some non-syntax error */
        {
          PyErr_Print ();
          free (code);
          code = NULL;
          prompt = ps1;
        }
        free (line);
      }
    }
    Py_XDECREF(glb);
    Py_XDECREF(loc);
    Py_Finalize();
    exit(0);
  }


5.16. ¾î¶»°Ô È®ÀåÀ» µð¹ö±×Çϳª¿ä?

gdb¸¦ µ¿ÀûÀ¸·Î ÀûÀçµÈ È®Àå°ú »ç¿ëÇÒ ¶§, È®ÀåÀÌ ÀûÀçµÇ±â Àü±îÁö´Â Á¤ÁöÁ¡À» ¼³Á¤ÇÒ ¼ö ¾ø½À´Ï´Ù.

.gdbinit ÆÄÀÏ¿¡¼­ (ȤÀº »óÈ£´ëÈ­ÀûÀ¸·Î), ¸í·É¾î¸¦ Ãß°¡Çϼ¼¿ä

br _PyImport_LoadDynamicModule

$ gdb /local/bin/python

gdb) run myscript.py

gdb) continue # repeat until your extension is loaded

gdb) finish # so that your extension is loaded

gdb) br myfunction.c:50

gdb) continue


5.17. Á¤ÀǵÇÁö ¾ÊÀº, ¸®´ª½ºÀÇ g++ ½Éº¼À» ¾î¶»°Ô ¹ß°ßÇϳª¿ä, __builtin_new ¶Ç´Â __pure_virtural

µ¿ÀûÀ¸·Î g++ È®Àå ¸ðµâÀ» ÀûÀçÇÏ·Á¸é, ÆÄÀ̽ãÀ» ´Ù½Ã ÄÄÆÄÀÏÇÏ°í, g++À» »ç¿ëÇÏ¿© ´Ù½Ã ¿¬°áÇØ¾ß ÇÕ´Ï´Ù (ÆÄÀ̽㠸ðµâÀÇ Makefile¿¡ ÀÖ´Â LINKCC¸¦ º¯°æÇϼ¼¿ä change LINKCC in the python Modules Makefile), ±×¸®°í ¿©·¯ºÐÀÇ È®Àå ¸ðµâÀ» g++À» »ç¿ëÇÏ¿© ¿¬°áÇØ¾ß ÇÕ´Ï´Ù (¿¹¸¦ µé¾î, "g++ -shared -o mymodule.so mymodule.o").


5.18. ³»Àå/È®Àå Çüµé¿¡ »óÀÀÇÏ´Â °´Ã¼µéÀ» ¾î¶»°Ô Á¤ÀÇÇÏ°í »ý¼ºÇմϱî?

º¸Åë ÀÌ·± Áú¹®À» ´øÁú¶§´Â ÆÄÀ̽ã ÇüÀ¸·ÎºÎÅÍ »ó¼ÓÀ» ¹Þ°í ½Í¾î¼­ÀÏ °ÍÀÔ´Ï´Ù. ÆÄÀ̽ãÀ» À§ÇÑ ÃÖ¼ÒÇÑÀÇ ¿¹°ßÇÒ ¼ö ÀÖ´Â ¹Ì·¡´Â: Çü°ú Ŭ·¡½º´Â ¼¯ÀÏ ¼ö ¾ø½À´Ï´Ù. Ŭ·¡½º¸¦ È£ÃâÇÏ¿© ½Çü¸¦ ±¸ÃàÇÏ°í, ¿©·¯ºÐÀÇ ¶æ´ë·Î ÇϺÎŬ·¡½º¸¦ ±¸ÃàÇÒ ¼ö ÀÖ½À´Ï´Ù.

±×·¸Áö¸¸, ÀÚ¹Ù¿Í ¸¶Âù°¡Áö·Î, ÆÄÀ̽ãÀº Á¦ÀÏ-Ŭ·¡½º(first-class) °´Ã¼¿Í Á¦ÀÌ-Ŭ·¡½º(second-class) °´Ã¼°¡ ÀÖ´Ù°í ÁÖÀåÇÕ´Ï´Ù (ÀüÀÚ´Â ÇüÀÌ°í, ÈÄÀڴ Ŭ·¡½ºÀÔ´Ï´Ù), ±×¸®°í ±× µÎ ½Öµ¿ÀÌ´Â Àý´ë·Î ¸¸³ªÁö ¾ÊÀ» °ÍÀÔ´Ï´Ù[¾Æ¸¶µµ].

±×·¸Áö¸¸, ¶óÀ̺귯¸®´Â ´õ ÀϹÝÀûÀ¸·Î ¿ä¸ÁµÇ´Â °´Ã¼µéÀ» À§ÇÑ Å¬·¡½º Æ÷ÀåÀÚ¸¦ ÈǸ¢ÇÏ°Ô Á¦°øÇÏ¿© ¿ÔÀ¸¸ç (¿¹Á¦¸¦ º¸½Ã·Á¸é UserDict, UserList ±×¸®°í UserStringÀ» ÂüÁ¶Çϼ¼¿ä), ±×¸®°í ¿©·¯ºÐÀÌ È¤½Ã³ª Äڵ带 ÀÛ¼ºÇÏ°í ½ÍÀº ±âºÐÀÌ µç´Ù¸é ¾ðÁ¦³ª ȯ¿µÇÏ°í ÀÖ½À´Ï´Ù.


¾ÕÀ¸·Î    ¸ñÂ÷    1    2    3    4    Á¦5Àå    6    7    8    ´ÙÀ½À¸·Î