ç§ãã¡ã®ãããžã§ã¯ãã®åã ã®éšåã¯25幎以äžåã®ãã®ã§ãããšããäºå®ã«ãããããããç§ãã¡ã¯èªåãã¹ããå°å ¥ããéã®ãŸãã«å§ãŸãã«éããŸããã ããã«ããããããããã§ã«ããã€ãã®æåãåããŠããŸããããã«ã€ããŠã¯ããã®èšäºã§èª¬æããŸãã
é©åãªèªåãã¹ãã®æžãæ¹ã¯ãå¥ã®èšäºã®ãããã¯ã§ãã ãããŠããããããã§ã¯ãããŸããã åã ã®ã³ã³ããŒãã³ãã®ãã¹ããã©ã®ããã«å®è£ ãããã説æããŸãã ã³ã³ããŒãã³ãã¯C ++ã§èšè¿°ãããŠãããCOMãšéåžžã«ãã䌌ãã€ã³ã¿ãŒãã§ãŒã¹ãåããŠããŸãã ãã¹ãã®èšèªãšããŠãPythonãéžæããéåžžã«åŒ·åãªPyTestãã¹ããã¬ãŒã ã¯ãŒã¯ã䜿çšããŸããã ãã®èšäºã§ã¯ãC ++ / COMãã³ãã«ãšPythonãã³ãã«ã®è€éããééããèœãšãç©Žãããã³ãããã®åé¡ã解決ããæ¹æ³ã«ã€ããŠèª¬æããŸãã
å 責äºé
- NDAã®ããããããžã§ã¯ãã®ã³ãŒããã³ããŒã¢ã³ãããŒã¹ãããããšã¯ã§ããŸããã ãããã£ãŠããã®èšäºã®ãã¹ãŠã®äŸã¯ãŒãããäœæãããŠããã決ããŠã³ã³ãã€ã«ãããŠããŸããã ãããã£ãŠã軜埮ãªäžæ£ç¢ºããæ§æãšã©ãŒããŸãã¯ã³ãŒãèšèšèŠåã®äžéµå®ãååšããå ŽåããããŸãã ããããç§ã¯äž»ãªæå³ãäŒããããšããŸããã
- ç§ã¯pythonã®å°é家ã§ã¯ãããŸããã å®ãèšããšããããžã§ã¯ãã®éäžã§pythonãæãå§ããŸããã ãããã£ãŠãPythonã«é¢ããããã€ãã®ã¹ããŒãã¡ã³ãã¯ãå®å šã«çå®ã§ã¯ãªãããå®å šã«è§£æ±ºãããŠããªãå¯èœæ§ããããŸãã
- äŸã®Pythonã³ãŒãã¯ãpep8ã«å¯Ÿå¿ããŠããªãå¯èœæ§ããããŸãã å€ãã®å ŽåãSOMãããã¿ã€ããåæ ãããã®ã¹ã¿ã€ã«ãåãå ¥ããŠããŸãã
- ãã®èšäºã¯cythonã®ããã¥ã¢ã«ã§ã¯ãããŸãããå€ãã®ãã®ãèå°è£ã«æ®ãããŠããŸãã
èæ¯
ç§ãåãçµãã§ãããããžã§ã¯ãã§ã¯ã倧èŠæš¡ã§è€éãªã¢ãžã¥ãŒã«ãéçºããŠããŸãã æ°çŸäžè¡ã®C ++ã³ãŒãã12åã®å€§ããªã³ã³ããŒãã³ãã100åã®dllãå éšã«ãããŸãã ãã®ã¢ãžã¥ãŒã«ã¯ãããã€ãã®å·šå€§ãªã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšãããŠããŸãã
æŽå²çã«ããã¹ãŠã¯UIãä»ããŠã®ã¿ãã¹ããããã»ãšãã©ã®éšåã¯æåã§ãã¹ããããŠããŸããã 1ã€ã®é åã®å€æŽãããŸã£ããå¥ã®å Žæã®ã©ããã«ãã°ãçºèŠããããšããããããŸãã ãããŠã圌ãã¯ãã®ãã°ãæ°æ¥ããããã¯æ°é±éåŸã«ããçºèŠããŸãã ãŸããå¥ã®è£œåãã¢ãžã¥ãŒã«ã®æ°ããããŒãžã§ã³ãçµ±åããããšã決å®ããæ°ãæåŸã«äœãããããã¢ããããããšããããŸãã
ã³ãããæã«CIã远跡ããåäœãã¹ãããããŸãã ããããTDDã«ã€ããŠè©±ãå§ãããšããã³ãŒãã¯15幎以äžãåã®ãã®ã§ããã ã³ãŒãã¯ã¢ããªã·ãã¯ã§ãåå¥ã«å®è¡ããã ãã§ã¯æ©èœããŸããã å€ãã®ãªãã¡ã¯ã¿ãªã³ã°ãå¿ èŠã§ããã誰ããªãœãŒã¹ãæäŸããŸããã ãããã£ãŠãåçŽãªé¢æ°ãŸãã¯åå¥ã®ã¯ã©ã¹ã®åäœãã¹ãã®ã¿ããããŸãã
ãã ããã¢ãžã¥ãŒã«ã«ã¯APIãããããããã®APIã䜿çšããŠãã®ã¢ãžã¥ãŒã«ããã¹ãã§ããŸãã åœç€Ÿã䜿çšãããã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ã®ãŠãŒã¶ãŒã±ãŒã¹ãåéããããã«é¢ããèªåãã¹ããäœæã§ããŸãã ãã®åŸãã³ãããæã«CIã§ãããã®ãã¹ããçŽæ¥å®è¡ã§ããŸãã ãã®ãããã³ã³ããŒãã³ããã¹ãã®ã¢ã€ãã¢ãçãŸããŸããã
ãããã誰ããã¹ããæžãã®ã§ããããïŒ ãã¹ã¿ãŒã¯åªãããã¹ãã¹ã¯ãªãããèãåºãããã¹ãããŒã¿ãæºåã§ããŸããããã¹ã¿ãŒã¯C ++ãç¥ããŸããïŒãããŠç¥ã£ãŠãã人ã¯ããã«éçºè ã«æšãŠãããŸãïŒã ããã°ã©ããŒã¯ãã®ãããªãã¹ããã³ãŒãã£ã³ã°ã§ããŸãããéåžžãããã€ãã®è¯å®çãªã·ããªãªã«å¯ŸããŠã¯ååãªãã¡ã³ã¿ãžãŒãããããŸããã ãã¹ãŠã®åŠå®çãªã±ãŒã¹ãã«ããŒããã«ã¯ãéåžžå¿èã ãã§ã¯ååã§ã¯ãããŸããã
é£ã®ããŒã ã®ååã®çµéšããåŠã¶ããšã«ããŸããã ã³ã³ããŒãã³ãã®ãµã€ããŒã©ãããŒãäœæãããã¹ãã«äœ¿çšããåçŽãªã€ã³ã¿ãŒãã§ã€ã¹ãPythonã§èšå®ããŸããã Pythonãå ¥åããããã®ãããå€ã¯ãC ++ãããã¯ããã«äœããªã£ãŠããŸãã ãã¹ã¿ãŒã¯æ°æ¥ã§ç°¡åã«pythonãç¿åŸã§ããåªããèªåãã¹ãã®äœæãéå§ã§ããŸãã
COMã¯ãããšäœã®é¢ä¿ããããŸããïŒ
ããªããç§ãã¡ã®èŠãã¿ã説æãå§ããåã«ãç§ãã¡ã®ã€ã³ã¿ãŒãã§ãŒã¹ã«ã€ããŠããã€ãã®èšèãèšãå¿ èŠããããŸãã ç§ãã¡ã¯ãCOMãçµã¿åãããŠLinuxããããŒããã©ã€ã«ç§»æ€ãããã¯ãããžãŒã䜿çšããŠããŸãã ã¬ãžã¹ããªã®æ¬ åŠã«é¢é£ããã€ã³ãã©ã¹ãã©ã¯ãã£ã®éããããã€ããããŸãããããã¯ãã®èšäºã«ãšã£ãŠéèŠã§ã¯ãããŸããã
COMã®ãããªæè¡ã¯ãæ¢è£œã®ãã©ã°ã€ã³ã³ã³ããŒãã³ãã€ã³ãã©ã¹ãã©ã¯ãã£ã®ãããªå€ãã®å©ç¹ãæäŸããŸãã ç°ãªãåœã®ç°ãªãããŒã ãäœæããã¢ãžã¥ãŒã«ïŒãµãŒãããŒãã£ã®ãã©ã°ã€ã³ãå«ãïŒãç°¡åã«ãããã³ã°ã§ããŸãã åæã«ãç°ãªãã³ã³ãã€ã©ãã©ã³ã¿ã€ã ãããã³æšæºã©ã€ãã©ãªéã®äºææ§ã®åé¡ã«ã€ããŠå¿é ããå¿ èŠã¯ãããŸããã ãŸãããã¹ãŠã®ã¢ãžã¥ãŒã«ã®ã€ã³ã¿ãŒãã§ãŒã¹ã®æäœããã©ã¡ãŒã¿ãŒãšæ»ãå€ã®è»¢éã«é¢ããåæããªããžã§ã¯ãã®åç¶æé-ãããã¯ãã¹ãŠãCOMãšåæ§ã®åæã«ãã£ãŠèŠå¶ãããŠããŸãã
è£è¿ãããããŸãã ã¢ãžã¥ãŒã«å ã§ã¯ãææ°ã®C ++æšæºã®ãã³ã䜿çšã§ããŸãã ãããããããªãã¯ã€ã³ã¿ãŒãã§ã€ã¹ã§ã¯ãCOMã®ã«ãŒã«ãéµå®ããå¿ èŠããããŸããåçŽåãŸãã¯IUnknownåŸç¶ã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ã§ãã STLã¯ãããŸããã å®è¡ãªããHRESULTã®ã¿ã ãã®ãããã¢ãžã¥ãŒã«ã®å¢çã«ããã³ãŒãã¯éåžžã«é¢åã§èªã¿ã«ããã§ãã
ã·ãã³ã®æåã®çµéš
ãŸããã¢ãžã¥ãŒã«ã®12åã®ã€ã³ã¿ãŒãã§ã€ã¹ãç¹å®ããŸãããããã«ãããå°èŠæš¡ãªããå®å šãªã¯ãŒã¯ãããŒãå®è£ ã§ããŸãã
ãããããããã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯ãããªãã¯APIã®äžéšã§ãããå®éã«ã¯éåžžã«äœã¬ãã«ã§ãã ç¹å®ã®æäœãè¡ãããã«ãåäžã®é¢æ°ãŸãã¯ã¡ãœãããååŸããŠåŒã³åºãããšã¯ã§ããŸããã 5ã€ã®ãªããžã§ã¯ããäœæããããããçžäºã«æ¥ç¶ããããããå®è¡ããŠãå°æ¥ã®çµæãåŸ ã€å¿ èŠããããŸãã ãã®å®å šãªè€éãã¯ããã©ã³ã¶ã¯ã·ã§ã³ãéåæãUndo / RedoãæŽçããã¹ã¬ããã»ãŒããªå éšãžã®ã¢ã¯ã»ã¹ããã®ä»ã®ããšãæŽçããããã«å¿ èŠã§ãã ã€ãŸããCOMã¹ã¿ã€ã«ã®C ++ã³ãŒãã®2ç»é¢ã
ååã®æšå¥šã«åŸããäœã¬ãã«ã®ã€ã³ã¿ãŒãã§ã€ã¹ãé ãå°ããªã¬ã€ã€ãŒãäœæããããšã«ããŸããã Pythonã§ã¯ãããã€ãã®é«ã¬ãã«é¢æ°ãå ¬éããããšãææ¡ãããŸããã
cythonã©ãããŒã¯ãc ++ã§åŒã³åºããåçŽã«è»¢éããŸããã
cdef class MyModuleObject(): cdef CMyModuleObject * thisptr # wrapped C++ object def __init__(self): self.thisptr = new CMyModuleObject() def __dealloc__(self): del self.thisptr def DoSomething1(self): self.thisptr.DoSomething1() def DoSomething2(self): self.thisptr.DoSomething2() def GetResult(self): return self.thisptr.GetResult()
CMyModuleObjectã¯ã©ã¹ã®C ++å®è£ ã¯ãã§ã«æçšãªããšãè¡ã£ãŠããŸããã¢ãžã¥ãŒã«ã®ãªããžã§ã¯ããäœæãããããã«ããã€ãã®æçšãªã¡ãœããïŒåã2ã€ã®ã³ãŒãç»é¢ïŒãåŒã³åºããŸãã
Cythonã¯æ¬è³ªçã«ç¿»èš³è ã§ãã äžèšã®ãœãŒã¹ã³ãŒãã«åºã¥ããŠãcythonã¯å€§éã®ã³ãŒããçæããŸãã dll / soãšããŠã³ã³ãã€ã«ããïŒãããŠpydã«ååãå€æŽããïŒãšãPythonã¢ãžã¥ãŒã«ãååŸãããŸãã CMyModuleObjectã®C ++å®è£ ããã®dllã«é 眮ããå¿ èŠããããŸãã ããã§ãPythonã¢ãžã¥ãŒã«ãpythonããã€ã³ããŒãã§ããããã«ãªããŸããïŒæåã«ã€ã³ããŒããã¹ã§å転ããŸããïŒã éåžžã®Pythonã€ã³ã¿ãŒããªã¿ãŒã䜿çšããŠèµ·åã§ããŸããäž»ãªããšã¯ãã¢ãŒããã¯ãã£ãäžèŽããããšã§ãã ã€ã³ããŒãè¡ãå®è¡ããããšã«ãããpythonã¯dllèªäœãååŸããå¿ èŠãªãã®ããã¹ãŠåæåããŠã€ã³ããŒãããŸãã
Pythonã¹ã¯ãªããã¯æ¬¡ã®ããã«ãªããŸããã
from my_module import * obj1 = MyModuleObject() obj1.DoSomething1() obj1.DoSomething2() print obj1.GetResult()
ãã£ãããïŒ C ++ãããã¯ããã«ç°¡åã§ãïŒ
æåã®æ®µéã§ã¯ããã¹ããã¬ãŒã ã¯ãŒã¯ã«ç ©ããããã®ã§ã¯ãªããæåã«éåžžã®ã¹ã¯ãªããã䜿çšããŠã¢ãããŒããå®è¡ããããšã«ããŸããã ãã®åœ¢åŒã§ã¯ããã§ã«äœããæžãããšãã§ããŸããããã®ã¢ãããŒãã¯æè»æ§ã«éãã¯ãããŸããã§ããã ã¬ã€ã€ãŒå ã®äœããå€æŽããå¿ èŠãããå Žåã¯ãC ++ã§ã³ãŒããå€æŽããå¿ èŠããããŸããã
COMã€ã³ã¿ãŒãã§ã€ã¹ã®ã¹ãããã£ã³ã°
ç§ã¯ãäœã¬ãã«ã®ã€ã³ã¿ãŒãã§ã€ã¹ãçŽæ¥ã¹ãããã£ã³ã°ããŠãå¿ èŠã«å¿ããŠPythonã§ã¬ã€ã€ãŒãäœæããããšããããšã䞻匵ããŸããã ãã®ã¢ã€ãã¢ã¯ã1察1ã®ã€ã³ã¿ãŒãã§ãŒã¹ããã³ããå ¬éAPIã®ã¬ãã«ã§ãã¹ãã§ãããšããäžåžã«è²©å£²ãããŸããã
ããã«èšã£ãŠãã£ãã ç§ãã¡ã¯ããã«ãã®ãããªèšç»ã«å°éããŸããã Pythonãªããžã§ã¯ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯COMãªããžã§ã¯ããäœæãããããžã®ãªã³ã¯ãææããŸãã ãã¡ããããªã³ã¯ã¯CComPtrã®ã¹ããŒãã³ããŒã³ããŒãšèŠãªãããŸãã
cdef class PyComponent: cdef CComPtr[IComponent] thisptr def __cinit__(self): # Get the COM host cdef CComPtr[IComHost] com_host result = GetCOMHost(IID_IComHost, <IUnknown**>&(com_host)) hresultcheck (result) # Create an instance of the component result = com_host.inArg().CoCreateInstance( CLSID_Component, NULL, IID_IComponent, <void**>self.thisptr.outArg() ) hresultcheck( result ) def SomeMethodWithParam(self, param): result = self.thisptr.inArg().SomeMethodWithParam(param) hresultcheck (result) def GetStringFromComponent(self): cdef char [1024] buf result = self.thisptr.inArg().GetStringFromComponent(buf, sizeof(buf)-1) hresultcheck(result) return string (buf)
éåžžãHRESULTé¢æ°ã¯èå³æ·±ããã®ã§ã¯ãããŸããã æ©èœãæåããå Žå-ãŸããããã ãããããŒã䜿çšããå Žåã¯ãããã«å ãžé²ãå¿ èŠã¯ãªãã§ãããã ãããã£ãŠããšã©ãŒã³ãŒãã確èªããPythonäŸå€ãã¹ããŒããã ãã§ãã æ»ãã³ãŒãã®åŠçã¯ãã¯ã©ã€ã¢ã³ãã®Pythonã³ãŒãã®ã¬ãã«ã§ã¯å®è¡ãããŸãããããã«ãããã¯ã©ã€ã¢ã³ãã³ãŒããå€§å¹ ã«ã³ã³ãã¯ãã«ãªããèªã¿ããããªããŸãã
class HRESULT_EXCEPTION(Exception): def __init__(self, result): super(HRESULT_EXCEPTION, self).__init__("Exception code: " + str(hex(result & 0xffffffff))) cpdef hresultcheck(HRESULT result): if result != S_OK: raise HRESULT_EXCEPTION(result)
hresultchecké¢æ°ã¯cpdefãšããŠå®£èšãããŠããããšã«æ³šæããŠãã ããã ããã¯ããã€ãã£ããªãã®ã ãã§ãªããPythonã®ãã®ïŒPythonã§ã¯hresultããŸã ãã§ãã¯ãããŠããããšãããïŒãšããŠåŒã³åºãããšãã§ããããšãæå³ããŸãã 2çªç®ã®ããããã£ã¯ãsitonã«ãã£ãŠçæããããšã©ãŒåŠçã³ãŒããå€§å¹ ã«åæžããå®è¡ãé«éåããŸãã SUCCEEDEDãã¯ãåŒã³åºãããã¹ã¿ãŒããŠããªãã®ã§ãS_OKãšæ¯èŒããŸã-ä»ã®ãšãããããã§ååã§ãã
ããã«ãããããããç¹å®ã®ã€ã³ã¿ãŒãã§ãŒã¹ãšãã®ã¡ãœãããç¹å®ã®æ¹æ³ã§ã®ã¿äœ¿çšããä»ã®äœã䜿çšããªãããšãæãããªå Žåã1察1ã®ã©ããã³ã°ããé¢ããããšããããŸããã ããšãã°ãCOMãªããžã§ã¯ãã空ã§äœæããããã®åŸãã©ã¡ãŒã¿ãŒãSet *ïŒïŒã¡ãœãããä»ããŠããŸãã¯äœããã®InitializeïŒïŒãåŒã³åºãããšã§ããã«è©°ã蟌ãŸãããšæ³å®ãããå Žåããã®å Žåã¯Pythonã¬ãã«ã§ãã©ã¡ãŒã¿ãŒã䜿çšããŠäŸ¿å©ãªã³ã³ã¹ãã©ã¯ã¿ãŒãå®è¡ããŸãã
ãŸãã¯ãå¥ã®äŸã瀺ããŸãã ãããªããžã§ã¯ããžã®ãªã¯ãšã¹ãã¯ãæŠå¿µçã«å¥ã®ãªããžã§ã¯ãïŒãŸãã¯åã«æ°ãããªããžã§ã¯ãïŒãžã®ãªã³ã¯ãè¿ãããšããããŸãã COMã§ã¯åºåãã©ã¡ãŒã¿ãŒã䜿çšããå¿ èŠããããŸãããPythonã§ã¯ãªããžã§ã¯ãã人éãè¿ãããšãã§ããŸãã
cdef class Class2: cdef CComPtr[IClass2] thisptr cdef class Class1: cdef CComPtr[IClass1] thisptr def GetClass2 (self): class2 = Class2() result = self.thisptr.inArg().GetClass2( class2.thisptr.outArg() ) hresultcheck ( result ) return class2
ã«ãã»ã«åã®èŠ³ç¹ããèŠããšãã³ãŒãã¯ããŸãè¯ããããŸãã-ãããªããžã§ã¯ããå¥ã®ãªããžã§ã¯ãã®è žã«äŸµå ¥ããŸãã ããããã«ãã»ã«åïŒããæ£ç¢ºã«ã¯ãã©ã€ãã·ãŒïŒãåããpythonã§ã¯ãããŸãè¯ããããŸããã ããããç§ãã¡ã¯ãŸã ãã£ãšçŸããæ¹æ³ãæãã€ããŠããŸããã 誰ããã¯ã©ã€ã¢ã³ãã³ãŒãã«æãå ¥ããŠClass2ãäœæããããšãããªã¹ã¯ããããŸãããããããããã§ã¯äœãåŸãããªãã§ãããã 誰ããPythonã®ãã©ã€ããŒãã³ã³ã¹ãã©ã¯ã¿ã®ãªãã·ã§ã³ãæããŠããããå¬ããã§ãã
äžèšã®ã³ãŒãäŸã¯ãpyxæ¡åŒµåãæã€ãã¡ã€ã«ã«ãããŸãïŒã¡ãªã¿ã«ããããããã¹ãŠ1ã€ã«ãŸãšããã®ã§ã¯ãªããå€ãã®ããšãå®è¡ã§ããŸãïŒã ããã®cppã®ãããªãã®ã§ã-å®è£ ãã¡ã€ã«ã§ãã ããããã·ãã³ã§ã¯ããŸã 宣èšãæã€ãã¡ã€ã«ãå¿ èŠã§ã-pxd-sishnyãšã¿ãªããããã¹ãŠã®ååãèšè¿°ãããå Žæã
from libcpp cimport bool from libcpp.vector cimport vector from libcpp.string cimport string from libc.stdlib cimport malloc, free cdef extern from "mytypes.h": ctypedef unsigned short int myUInt16 ctypedef unsigned long int myUInt32 ctypedef myUInt32 HRESULT ctypedef struct GUID: pass ctypedef enum myBool: kMyFalse kMyTrue kMyBool_Max cdef extern from "hresult.h": cdef HRESULT S_OK cdef HRESULT S_FALSE cdef extern from "Iunknown.h": cdef cppclass IUnknown: HRESULT QueryInterface (const IID & iid, void ** ppOut) HRESULT AddRef () HRESULT Release () cdef extern from "CComPtr.h": cdef cppclass CComPtr [T]: # this is trick, to assign pointer into wrapper T& assign "operator="(T*) T* inArg() T** outArg() cdef extern from "comhost.h": cdef extern IID IID_IComHost cdef cppclass IComHost(IUnknown): HRESULT CoCreateInstance ( const GUID& classid, IUnknown* pUnkOuter, const IID& iid, void** x )
CComPtr :: operator =ïŒïŒã«æ³šæããŠãã ããã sitonã³ãŒãã§CComPtrã«çŽæ¥å²ãåœãŠãããšãããšãäœãæ©èœããŸããã 圌ã¯åã«ãã®æ§ææ§é ãé©åã«è§£æã§ããŸããã ç§ã¯ãã£ã©ã¯ã¿ãŒã®ååãå€æŽããããªãã¯ã«é Œããªããã°ãªããŸããã§ããã å²ãåœãŠã¯ããã£ã©ã¯ã¿ãŒãã·ãã³ã§ã©ã®ããã«èŠãããã§ãããåŒçšç¬Šã§ã¯ãã³ãŒãã§åŒã³åºãå¿ èŠããããã®ãæ£ç¢ºã«èšå®ããŸãã
ãã®ããªãã¯ã¯ãsyslogãšåãæ¹æ³ã§Pythonã¯ã©ã¹ãŸãã¯é¢æ°ãåŒã³åºãå¿ èŠãããå Žåã«åœ¹ç«ã¡ãŸãã
pxdïŒ
cdef extern from "MyFunc.h": int CMyFunc "MyFunc" ()
pyxïŒ
def MyFunc(): CMyFunc()
ãããžã§ã¯ãã«æ»ããŸãã Pythonã³ãŒãã¯ããã«ã·ã³ãã«ã§ã³ã³ãã¯ãã§ãããã»ãšãã©ã®ãŠãŒã¶ãŒã«ãšã£ãŠã¯äœã¬ãã«ã§ãã ãããã£ãŠãç§ãã¡ã¯ãŸã ã¬ã€ã€ãŒãæ®ããŠãPythonã§æžãçŽãããšã«ããŸããã ãã®çµæããããã®2ããŒãžã®ããã°ãCOMã³ãŒãã¯ããã«ãªããŸãã
def do_operation(param1, param2): operation = DoSomethingOperation(param1, param2) engine = TransactionEngine() future = engine.Submit(operation) future.Wait() return future.GetResult()
ãã®ãããã³ãŒãã¯ã¯ããã«ã³ã³ãã¯ãã§ç解ãããããªããdo_operationïŒïŒãªã©ã®é«ã¬ãã«ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããå¿ èŠã«å¿ããŠãã€ã³ã¿ãŒãã§ã€ã¹ãã€ã³ã¿ãŒãã§ã€ã¹ã«ç§»åããããšãã§ããŸããã
æè»æ§ã®æèŠããããæ¯åC ++éšåãåã³ã³ãã€ã«ããå¿ èŠã¯ãããŸããã§ããã ããã«ãæåã¯10åã®ã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ãã¹ãããã£ã³ã°ããå¿ èŠãããããã®åŸã®åæ©èœã§ã¯1ã2åã®ã¿ãã¹ããŒãºããå¿ èŠããããŸããã
åé¡ãå§ãŸã
ãã®åœ¢åŒã§ã¯ããã®ãã¯ãããžãŒã¯ãã§ã«ã»ãšãã©ã®ãããžã§ã¯ãã«é©ããŠãããããããŸããããããã€ãã®åºæ¬çãªå¶éã«çŽé¢ããŸããã
ãããã£ãŠãCOMãã¹ãïŒCOMã€ã³ãã©ã¹ãã©ã¯ãã£ãããããçš®é¡ã®CoCreateInstanceãªã©ãæäŸãããªããžã§ã¯ãïŒã¯ãéåžžã®ãã©ã¹ãªããžã§ã¯ãã§ãã ãã®ããã誰ãããããäœæïŒCoInitialize analogïŒããŠããåé€ïŒCoFinalizeïŒããå¿ èŠããããŸãã ããããããã«åé¡ããããŸããPythonã¢ãžã¥ãŒã«ã«ã¯mainïŒïŒããããŸããã ãããã«ããŠããå¿ èŠãªåœ¢ã§ã
ãããã£ãŠãããžãã£ãã¢ããªã±ãŒã·ã§ã³ãªããžã§ã¯ããäœæãããã®ãªããžã§ã¯ãã«ãã¹ãã®åæå/ãã¡ã€ãã©ã€ãºãé 眮ããŸããã 圌ãã¯ãPythonãããã®ãªããžã§ã¯ããïŒåã¹ã¯ãªããã®æåã«ïŒäœæã§ããããã«ããã©ãããŒãäœæããŸããã
ããããéåžžã«è¿ éã«ãåºå£ã§ã¯ã©ãã·ã¥ãçºèŠãå§ããŸããã C ++ïŒæåã«äœæããããªããžã§ã¯ãã¯æåŸã«åé€ãããŸãïŒãšã¯ç°ãªããPythonã§ã®ãªããžã§ã¯ãã®ç Žå£é åºã¯å®çŸ©ãããŠããŸããã ãŸãããããã«ããŠãã圌ã«åœ±é¿ãäžããæ¹æ³ã¯ãããŸããã ã ãŒã³ãã§ãŒãºã«å¿ããŠãPythonã¯æåã«Applicationãªããžã§ã¯ããéä»ãã«ããCOMã€ã³ãã©ã¹ãã©ã¯ãã£ãæ¶æ» ããããã¹ãŠã®ã³ã³ããŒãã³ãã匷å¶çã«ã¢ã³ããŒãããŸããã ãã®åŸãPythonã¯SOMãªããžã§ã¯ããžã®ãªã³ã¯ãæã€ä»ã®ãªããžã§ã¯ããåé€ããŸããã ãã§ã«ã¢ã³ããŒããããdllããReleaseïŒïŒãåŒã³åºãããšãããšãã¯ã©ãã·ã¥ããŸããã
2çªç®ã®åé¡ã¯ãå®è¡å¯èœãã¡ã€ã«ã®å Žæã§ãã 倧èŠæš¡ãªã³ã³ããŒãã³ãã«ã¯ãå®è¡å¯èœãã¡ã€ã«ãåºæºãšããäœããã®ãã¹ã«æ²¿ã£ãŠããŒã¿ãå«ããã¡ã€ã«ãéãããšããå ŽæãããããããããšãããããŸããã æçµçãªã¢ããªã±ãŒã·ã§ã³ãäœããã®æ¢ç¥ã®æ¹æ³ã§ã·ã¹ãã ã«ã€ã³ã¹ããŒã«ãããŠããå Žåãããã¯æ£åžžã§ãã ããã¯ãäœæ¥ãã£ã¬ã¯ããªã§ã³ã³ãã€ã«ãããã¢ããªã±ãŒã·ã§ã³ã§äœæ¥ããŠããå Žåãæ£åžžã§ãã ããããå®è¡å¯èœãã¡ã€ã«ãã·ã¹ãã ãã£ã¬ã¯ããªã§çªç¶pythonã«ãªã£ãå Žåããã®ã¡ãœããã¯æ©èœããªããªããŸãã
ã¢ããªã±ãŒã·ã§ã³ãã£ã¬ã¯ããªãåå®çŸ©ã§ããæ©èœããããŸããã ããã¯ã»ãšãã©ã®å Žåã«æ©èœããŸããã ããããæ®å¿µãªããšã«ããã®åå®çŸ©ãç¡èŠããŠãå®è¡å¯èœãã¡ã€ã«ã«å¯Ÿããçžå¯Ÿãã¹ãç¬èªã«èšç®ãç¶ããèªè»¢è»ãã«ããŒãããŸããã ãããåãåã£ãŠä¿®æ£ããã®ã¯æ£ããããšã§ãããããªãã®åŽåãå¿ èŠã«ãªããŸãã ããã¯ãŸã æªåŠçã®ãŸãŸã§ãããšå€æããŸããã
æåŸã«ã3çªç®ã®åé¡ã¯ã€ãã³ãã«ãŒãã§ãã å®éããã®ã¢ãžã¥ãŒã«ã¯éåžžã«è€éã§ã€ã³ã¿ã©ã¯ãã£ãã§ãã ããã¯ãåãªããé¢æ°ã®åŒã³åºã-çµæã®ååŸãã¹ã¿ã€ã«ã©ã€ãã©ãªã§ã¯ãããŸããã ããã¯å·šå€§ãªåç©«æ©ã§ãã å éšã§ã¯ããªããšãã¡ãã»ãŒãžã亀æããæ°çŸã®ã¹ã¬ãããå転ãããŸãã ã³ãŒãã®äžã«ã¯äžç代ã®éã«æžããããã®ããããã¡ã€ã³ã¹ã¬ããã§ã®ã¿å®è¡ãããããšãæå³ããŠããŸãïŒãã以å€ã§ã¯åäœããŸããïŒã ä»ã®å Žæã§ã¯ãã¡ãã»ãŒãžã¯ããŒãã³ãŒãã«ãã£ãŠã¡ã€ã³ã¹ã¬ããã«éä¿¡ãããããã«ãã®ã¡ãã»ãŒãžã®åŠçæ¹æ³ãç¥ã£ãŠããããšãæåŸ ãããŸãã ãŸããç¬èªã®ã¹ããªãŒã ãšã¡ãã»ãŒãžã®ãµãã·ã¹ãã ããããŸããããã¯ãã¡ãã»ãŒãžåŠçãµã€ã¯ã«ãã¡ã€ã³ã¹ããªãŒã ã§ç¢ºå®ã«ã¹ãã³ããããããã¹ãŠå®è¡ããããšãæå³ããŸãã ãããªãã§ã¯ä»æ¹ãããŸããã
æåã®æãç°¡åãªè§£æ±ºçã¯ãã¢ããªã±ãŒã·ã§ã³ã¯ã©ã¹ã«run_event_loopïŒïŒã¡ãœãããæ¿å ¥ããã¡ãã»ãŒãžã«ãŒãããããããšã§ããã æçšãªäœæ¥ãå®äºãããšãããã»ã¹ã¯åæ¢ããŸããïŒçŸåšç解ããŠããããã«ãããã¯å¶ç¶ã®äžèŽã«ãã£ãŠçºçããŠããŸãã:)ïŒ
äžè¬ã«ããã®ãããªã¹ã¯ãªããã¯æ£åžžã«æ©èœããŸããããã³ããããã³ã°é¢æ°ïŒçµäºãåŸ ããªãïŒã䜿çšããŠäœæ¥ãéå§ãããã®åŸã€ãã³ãã«ãŒãã«åãããŸãã
app = Application() start_some_processing_async() app.run_event_loop()
ããããããã€ãã®åæ¹åæ§ãå¿ èŠãšããã·ããªãªã§ã¯ãåé¡ãå€æããŸããã ããšãã°ãäœæ¥ãéå§ã§ãããæ°ç§åŸã«åæ¢ããããšããŸããã å®éãã¡ã€ã³ã¹ã¬ããã®ã¡ãã»ãŒãžåŠçãµã€ã¯ã«ãéå§ããããŸã§ãäœæ¥ã¯éå§ãããŸããã§ããã ãµã€ã¯ã«ãéå§ããå ŽåãPythonã«ã¯æ»ããŸããã
ãã¡ãããPythonã¬ãã«ã§éåæã®äœãããã§ã³ã¹ããããšãå¯èœã§ãããããã¯æããã«ç§ãã¡ãæããã®ã§ã¯ãããŸããã çµå±ã®ãšããããã®ã¢ãããŒãã¯ãéåæã·ã¹ãã ã«èªæãããŠããªã人ã ãããã·ã¥ããããšã«ãªã£ãŠããã 圌ãã¯ãã®ããã«æžããŠãã€ãã³ãã«ãŒãã§ã¹ããŒã ãã¹ã济ã³ãããªã
start_some_processing_async() time.sleep(3) cancel_processing()
èãçŽãããšãªããå¥ã®ã¹ã¬ããã§åŠçãéå§ããã¡ã€ã³ã§ã¡ãã»ãŒãžã«ãŒããã²ãããŸããã ããããããã«æ¬¡ã®åé¡ã«ééããŸãã-GILïŒGlobal Interpreter LockïŒ ã Pythonicã¹ã¬ããã¯å®éã«ã¯äžŠè¡ããŠå®è¡ãããŠããªãããšãå€æããŸããã äžåºŠã«å®è¡ãããã¹ã¬ããã¯1ã€ã ãã§ãããã¹ã¬ããã¯100ã³ãã³ãããšã«åãæ¿ããããŸãã ãã®ãã¹ãŠããã®åãGILãèŠå¶ãã1ã€ãé€ããã¹ãŠã®ã¹ã¬ãããåæ¢ããŸãã
ã¡ã€ã³ã¹ã¬ãããapp.run_event_loopïŒïŒé¢æ°ã«è¡ã£ãŠæ»ã£ãŠããªãã£ãå ŽåïŒããã³èšèšäžããã³ã°ããå¿ èŠãããå ŽåïŒãä»ã®ã¹ã¬ããã®ä»ã®Pythonã³ãã³ãã¯å®è¡ãããªãããšãå€æããŸããã ã¡ã€ã³ã¹ã¬ããã«ãã以äž100åã®ã³ãã³ãããªãã£ãããšã ãã§ãã€ã³ã¿ãŒããªã¿ãŒã¯åãæ¿ããã«ã¯æ©ããããšå€æããŸããã
解決çã¯nogil sitonããŒã¯ãŒãã§èŠã€ãããŸããã nogilãšããŒã¯ãããã³ãŒãã¯ãæåã«GILã解æŸããŠãããã·ã¹ãã ãåŒã³åºããŸãã æåŸã«ãGILãåã³ãã£ããã£ãããŸãã T.O. ã¡ã€ã³ã¹ã¬ããã¯GILã解æŸããã¡ãã»ãŒãžã«ãŒãã«å ¥ããŸããã 2çªç®ã®ã¹ã¬ãããå¶åŸ¡ãåããå¿ èŠãªãã¹ãŠãè¡ããŸããã
def Func(self): result = 0 cdef IComponent * component = self.thisptr.inArg() with nogil: result = component.Func() hresultcheck(result)
ã¡ãªã¿ã«ãã·ãã³ã¯éåžžã«äžæ©å«ãªãã®ã§ãã Pythonã³ãŒããš1è¡ã®ã³ãŒãã«å¹²æžã§ãããšã¯éããŸããã ãŸããäžéšã®Pythonæ§é äœãåŒã³åºããããnogilã»ã¯ã·ã§ã³ã§æ°ããå€æ°ãäœæãããããããšãã§ããŸããïŒè«ççã«ã¯ãããã«ã¯GILã«ãã£ãŠä¿è·ãããŠããPythonã®è žãžã®ã¢ã¯ã»ã¹ãå¿ èŠã§ãïŒã å€æ°ãæ£ãã宣èšããå¿ èŠãªåŒã³åºããè¡ãã«ã¯ããã®ããã«åããªããã°ãªããŸããã
ãã¹ãŠãæ©èœãå§ããããã«èŠããŸããããéåžžã«äžå®å®ã§ãã ç§ãã¡ã¯çµ¶ããããçš®ã®ã¯ã©ãã·ã¥ãšãã³ã°ããã£ããããã¢ã€ãã«æ©èœã«ã€ãŸãããŸããïŒãã¡ã€ã«ã¯çžå¯Ÿãã¹ã§éãããŸããã§ãããã誰ããšã©ãŒãæããŸããã§ããïŒã
ä»ã®æ¹æ³ã§èšèšãã
æ°é±éããããã®3ã€ã®åé¡ã解決ããããŸããŸãªã¢ãããŒããè©Šã¿ãŸããã ããããæ¯åå¥ã®è§£æ±ºã§ããªãåé¡ããããŸããã GILã¯äœãããé ä¿¡ããŸããããCOMãã¹ãã®ã¢ã³ããŒããç¡å¹ã«ããæ¹æ³ãããããŸããã§ããã
luaã«ãžã£ã³ãããããšããèããŸããããå¶éã®ããã€ãã¯ãŸã æ®ã£ãŠããŸãã ãã®å Žåã«ã®ã¿ãæåãããã¹ãŠãå®è¡ããå¿ èŠããããŸãã
ãããããã®åŸã倧èãªã¢ã€ãã¢ãæµ®äžããŸããã ããããpythonããsyshã³ãŒãã§ã¯ãªããsyshããpythonãå®è¡ãããšã©ããªããŸããïŒ æ¬¡ã®ããšãè¡ãã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã
- COMãã¹ãã®åæå
- 2çªç®ã®ã¹ã¬ãããéå§ãã
- ã¡ã€ã³ã¹ã¬ããã§ãã€ãã³ãã«ãŒããå®è¡ãã
- 2çªç®ã®ã¹ã¬ããã§ãPythonã€ã³ã¿ãŒããªã¿ãŒãå®è¡ããŸãïŒä»ã®ã¢ããªã±ãŒã·ã§ã³ã«åã蟌ãããã®å¯Ÿå¿ããAPIããããŸãïŒ
ãã®ã¢ãããŒãã¯ã3ã€ã®åé¡ãã¹ãŠãäžæã«è§£æ±ºããŸãã
- COMãã¹ãã®ã©ã€ãã¿ã€ã ãå¶åŸ¡ããPythonã¹ããªãŒã ãåŠçãçµäºããåŸããã®ç Žå£ãä¿èšŒã§ããŸãã
- ãã¹ãã¢ããªã±ãŒã·ã§ã³ã¯ã¡ã€ã³è£œåã®é£ã«é 眮ãããŸããã€ãŸãããã¹ãŠã®çžå¯Ÿãã¹ãæ©èœããŸãã
- æåŸã«ãGILã«åé¡ã¯ãããŸããã Pythonã¯ã·ã³ã°ã«ã¹ã¬ããã¹ã¯ãªãããå®è¡ããŸããã€ãŸãããªãœãŒã¹ã誰ãšãå ±æããå¿ èŠã¯ãããŸããã
ç¥ã£ãŠãïŒ ãã®ã¢ãããŒãã¯ããŸããããŸããïŒ ããããæçµçã«è§£æ±ºãããããã€ãã®å°ããªåé¡ããããŸãã
- ã¡ã€ã³ã¹ã¬ããã§ããã€ãã®åŒã³åºããè¡ãå¿ èŠããããŸãã ãŸããäœããç§ãã¡ã¯ã¡ãã»ãŒãžãã¡ã€ã³ã¹ã¬ããã«åŒã蟌ã¿ãäœãå¿ èŠããå°ããŸããã
- PYTHON_HOMEãšPYTHON_PATHã®ã€ã³ã¹ããŒã«ã«ããªãæãå ããå¿ èŠããããŸããã éèŠãªç¹ã¯ãPythoné¢æ°Py_SetPythonHomeïŒïŒãæšæºã®setenvïŒïŒãæž¡ãããæååãããèªäœã«ã³ããŒããã®ã§ã¯ãªããåã«ãã€ã³ã¿ãŒãèŠããŠããããšã§ãã ç§ãã¡ã®å Žåãããã¯äžæå€æ°ãžã®ãã€ã³ã¿ã§ããã
- Pythonã®ããŒãžã§ã³ã«äŸåããªãããã«ããããã«ããã¹ãŠã®ã¬ãããæã¡æ©ãããšã«ããŸããã æšæºã©ã€ãã©ãªïŒå€æããããã«ãzipããçŽæ¥èªã¿åããŸãïŒãšããã€ãã®è¿œå ã©ã€ãã©ãªãå«ã
ç§ãããããåããªããã°ãªããªãã£ãå¥ã®åé¡ã¯ãsys.exitïŒïŒé¢æ°ã§ããã unittestããã®æ»ãã³ãŒãããã£ããããŠåºåã«æž¡ããCIã§åŠçããããã«å¿ èŠã§ããã
ãã®ããã«åäœããŸãã ã¹ã¯ãªããå ã®èª°ããsys.exitïŒïŒãåŒã³åºããšãSystemExitäŸå€ãå®éã«ã¹ããŒãããŸãã ãã®äŸå€ã¯Pythonèªèº«ã«ãã£ãŠãã£ãããããã°ããŒãã«ã«ãã£ãããããä»ã®äŸå€ãšåæ§ã«ãã¹ã¿ãã¯ãã¬ãŒã¹ãšãšãã«ã³ã³ãœãŒã«ã«åºåããå¿ èŠããããŸãã ããããPy_PrintExé¢æ°ã¯ãã®ãããªç¹å¥ãªã±ãŒã¹ãããããšãç¥ã£ãŠãããSystemExitäŸå€ãåºåããããã«ææ¡ãããå ŽåãexitïŒïŒãåŒã³åºãå¿ èŠããããŸãã
ã¯ããããã§ãïŒ Printãšããé¢æ°ã¯ãexitïŒïŒåŒã³åºããè¡ããŸãã ãããŠããã®åºå£ã¯æ£çŽã«å®çŸããŸã-ã¢ããªã±ãŒã·ã§ã³å šäœãååŸããŠåæžããŸãã ãããŠåœŒã¯ãã¢ããªã±ãŒã·ã§ã³ã«æªãªãªãŒã¹ã®ãã³ãã«ãäžå®å šãªã¹ããªãŒã ãéããããŠããªããã¡ã€ã«ãæçµåãããŠããªãã¢ãžã¥ãŒã«ã100äžã®ã¢ã¯ãã£ããªã¹ã¬ããããããŠãã¹ãŠã®ãžã£ãºããããšããäºå®ãåãåºãããã£ãã®ã§ãã
ããããpythonïŒã©ããªå Žåã§ã2.7.6ããžã£ã³ã¯ãç§ã¯ç¥ã£ãŠããŸãïŒã¯ããããAPIã¬ãã«ã§èª²çšããããšãèš±å¯ããŸããã pythonãœãŒã¹ãããããžã§ã¯ãã«ããã€ãã®é¢æ°ãã³ããŒãïŒPyRun_SimpleFileExFlagsïŒïŒãšãããåŒã³åºãããã€ãã®ãã©ã€ããŒããªé¢æ°ããïŒãèªåã§ãããçµäºããå¿ èŠããããŸããã ãã®ãããSystemExitã®å Žåã®ããŒãžã§ã³ã¯æ£ããçµäºãããªã¿ãŒã³ã³ãŒããè¿ããŸãã T.O. pythonéšåã®å®äºåŸã®ãã¹ãã¢ããªã±ãŒã·ã§ã³ã¯ãããèªäœãæ£ãããããã«ããŠæ¶ãããšãã§ããŸãã
æåã¯2人ã®ãã¶ã€ããŒãããŸããã1人ã¯çµã¿èŸŒã¿ã®pythonã䜿çšããŠãã¹ãã¢ããªã±ãŒã·ã§ã³ãäœæãã2人ç®ã¯ä»¥åã®ããã«pythonã®ããŒãå¯èœãªã¢ãžã¥ãŒã«ãäœæããŸããã ããããåŸã§ãã¹ãŠã1人ã®ãã¶ã€ããŒã«çµåããŸããã ãã¹ãã¢ããªã±ãŒã·ã§ã³ã¯pythonãåæåããåŸãPythonã¢ãžã¥ãŒã«ïŒsitonã«ãã£ãŠçæãããïŒã®åæåé¢æ°ãåŒã³åºããŸããã T.O. æ¢ã«éå§æã®pythonã¯æ¢ã«ã¢ãžã¥ãŒã«ãç¥ã£ãŠããŸããïŒã€ã³ããŒãã¯ãŸã è¡ãããŠããªããã°ãªããŸããã§ããïŒã
ã³ãŒã«ããã¯
ãã®ãã©ãŒã ã§ã¯ããã¹ãã¢ããªã±ãŒã·ã§ã³ãéåžžã«åªããŠããããšãããããŸããã ãã¹ããã¬ãŒã ã¯ãŒã¯ïŒæšæºãŠããããã¹ãïŒãå°ç¡ãã«ããŠããã¹ã¿ãŒã¯å°ããã€ãã¹ããæžãå§ããŸããã ãã®éãç§ãã¡èªèº«ãã€ã³ã¿ãŒãã§ãŒã¹ãã©ãããç¶ããŸããã
å¥ã®æ©èœãå°ç¡ãã«ããŠããŸã£ããããå Žåã«ãã£ãŠã¯ã³ãŒã«ããã¯ãåãå ¥ããå¿ èŠããããšããäºå®ã«åºäŒããŸããã ã€ãŸã Pythonã¯é¢æ°ãåæçã«åŒã³åºãããã®è žã§Pythonãžã®ã³ãŒã«ããã¯ãåŒãèµ·ãããŸãã
plusã€ã³ã¿ãŒãã§ãŒã¹ã¯æ¬¡ã®ããã«ãªããŸãã
class ICallback : public IUnknown { virtual HRESULT CallbackFunc() = 0; }; Class IComponent : public IUnknown { virtual HRESULT MethodWithCallback(ICallback * cb) = 0; };
Pythonã¯ã©ã¹ã¯ããœãŒã¹ã®äžã®plusã€ã³ã¿ãŒãã§ã€ã¹ããç¶æ¿ã§ããŸããã ãããã£ãŠããããžã§ã¯ãã®ã·ã¹ãã éšåã§ã¯ãPythonã«åŒã³åºãã転éããç¬èªã®å®è£ ãäœæããå¿ èŠããããŸããã
.h
//Forward declaration struct _object; typedef struct _object PyObject; class CCallback : public ICallback { //COM stuff ... CCallback * Create(); // ICallback virtual HRESULT CallbackFunc(); public: void SetPythonCallbackObject(PyObject * callback_handler); private: PyObject * m_pPythonCallbackObject; };
.cpp
const char PythonMethodName[] = "PythonCallbackMethod"; void CCallback::SetPythonCallbackObject(PyObject * callback_handler) { // Do not addref to avoid cyclic dependency m_pPythonCallbackObject = callback_handler; } HRESULT CCallback::CallbackFunc() { if(!m_pPythonCallbackObject) return S_OK; // Acquire GIL PyGILState_STATE gstate = PyGILState_Ensure(); if ( gstate == PyGILState_UNLOCKED ) { // Call the python method char * methodName = const_cast<char *>(PythonMethodName); //Py_Api doesn't work with constant char * PyObject * ret = PyObject_CallMethod(m_pPythonCallbackObject, methodName, NULL); if (!ret) { if (PyErr_Occurred()) { PyErr_Print(); } std::cout<<"cannot call"<<PythonMethodName<<std::endl; } else Py_DecRef(ret); } // Release the GIL PyGILState_Release(gstate); return S_OK; }
ãã®ã³ãŒãã®ç¹å¥ãªç¬éã¯ãGILã®ãã£ããã£ã§ãã ããã§ãªãå ŽåããããããPythonã¯GILããã£ããã£ãããŠããããšã確èªãããšå£ããŸãããã»ãšãã©ã®å Žåããã³ã°ããããã¹ãããŸãã
ã³ã³ãœãŒã«ã¢ããªã±ãŒã·ã§ã³ããããããã³ã³ãœãŒã«ãžã®ãšã©ãŒåºåã§ãã Pythonã³ãŒããäŸå€ãã¹ããŒããå Žåã§ãããã³ãã©ãŒã¯äŸå€ããã£ããããŠãã¬ãŒã¹ããã¯ãåºåããŸãã
ã·ãã³ã®åŽé¢ããã¯ã次ã®ããã«ãªããŸãã
cdef class PyCallback (object): cdef CComPtr[ICallback] callback def __cinit__(self): self.callback.assign( CCallback.Create() ) self.callback.inArg().SetPythonCallbackObject(<PyObject *> self) def PythonCallbackMethod(self): print "PythonCallbackMethod called" cdef class Component: cdef CComPtr[IComponent] thisptr def __cinit__(self): // Create IComponent instance ... def CallMethodWithCallback(self, PyCallback callback): cdef IComponent * component = self.thisptr.inArg() cdef ICallback * cb = callback.callback.inArg() hresult = 0 with nogil: hresult = component.MethodWithCallback(cb) hresultcheck(hresult)
MethodWithCallback() GIL, .
component = Component() callback = PyCallback() component.CallMethodWithCallback(callback)
, . , API, cython.
, . , , . , GIL ( , ), . PyGILState_Ensure() , , , .
, , , . , , , . .
. , , . PyRun_FileExFlags(), , PyArena_Free()
PyThreadState *_save = PyEval_SaveThread(); while (GetCurrentlyActiveCallbacks() > 0) ; // semicolon here is correct PyEval_RestoreThread(_save);
ãããã«
python->cython->C++ API . , . . , â .
, . ++/ . .
PyTest . ! , .
, . , , , - . .
. cython' . .
Cython . , , . .
. , . â :
PyRun_InteractiveLoop(stdin, "<stdin>");
++ IDE. , CI . ++ . . , â PyTest .
, . . , .
, , - .