📄 pythoninterpreterimpl.cpp
字号:
//// This file is part of the "More for C++" library//// Copyright (c) 1999-2003 by Thorsten Goertz (thorsten@morefor.org)//// The "More for C++" library is free software; you can redistribute it and/or// modify it under the terms of the license that comes with this package.//// Read "license.txt" for more details.//// THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES// OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.////////////////////////////////////////////////////////////////////////////////#include <more/create.hpp>#include <more/platform.hpp>#include <more/os/thread.hpp>#include <more/util/threadcontext.hpp>#include "pythoninterpreterimpl.hpp"using namespace more;using namespace more::io;using namespace more::os;using namespace more::script;using namespace more::util;typedef ThreadContextHolder<p<OutputStream> > ThreadOutputStreamHolder;typedef ThreadContextBinder<p<OutputStream> > ThreadOutputStreamBinder;////////////////////////////////////////////////////////////////////////////////const char* PythonInterpreterFactory::getLanguage( ){ return "Python";}////////////////////////////////////////////////////////////////////////////////InterpreterPtr PythonInterpreterFactory::createInterpreter( ){ return CREATE PythonInterpreterImpl( );}////////////////////////////////////////////////////////////////////////////////void PythonInterpreterFactory::init( ){ static PyMethodDef moreEmbeddingMethodDefs[2] = { { "write", PythonInterpreterFactory::write, METH_VARARGS, "" }, { 0, 0 } }; CREATE ThreadOutputStreamHolder( ); Py_Initialize( ); PyEval_InitThreads( ); pMainThreadState = PyThreadState_Get( ); Py_InitModule( "more_embedding", moreEmbeddingMethodDefs ); PyRun_SimpleString( "import more_embedding" "\n" "import sys" "\n" "" "\n" "class StdOutAdapter( object ):" "\n" " def write( self, o ):" "\n" " more_embedding.write( str( o ) )" "\n" "" "\n" "sys.stdout = StdOutAdapter( )" "\n" "sys.stderr = sys.stdout" "\n" ); PyEval_ReleaseLock( ); InterpreterFactory::init( );}////////////////////////////////////////////////////////////////////////////////void PythonInterpreterFactory::dispose( ){ InterpreterFactory::dispose( ); PyEval_AcquireLock( ); PyThreadState_Swap( PyThreadState_New( pMainThreadState -> interp ) ); Py_Finalize( );}////////////////////////////////////////////////////////////////////////////////PyObject* PythonInterpreterFactory::write( PyObject* pSelf, PyObject* pParameters){ try { p<OutputStream> pOutputStream = ThreadOutputStreamHolder::getBoundData( ); const char* pcString; int nLength; if( pOutputStream != 0 && PyArg_ParseTuple( pParameters, "s#", &pcString, &nLength) ) { pOutputStream -> write( pcString, nLength ); } } catch( ... ) { } Py_INCREF( Py_None ); return Py_None;}////////////////////////////////////////////////////////////////////////////////PyThreadState* PythonInterpreterFactory::pMainThreadState = 0;////////////////////////////////////////////////////////////////////////////////void PythonInterpreterImpl::registerNativeModule( const String& sModule, PyMethodDef* pMethodDefs){ synchronized_py { const char* pcModule = sModule; Py_InitModule( ( char* ) pcModule, pMethodDefs ); } end_synchronized}////////////////////////////////////////////////////////////////////////////////void PythonInterpreterImpl::registerExtensionType( const String& sModule, PyTypeObject* pTypeObject){ static PyMethodDef emptyMethodDefs[1] = { { 0, 0 } }; synchronized_py { PyObject* pPythonModule; const char* pcModule = sModule; PyType_Ready( pTypeObject ); pPythonModule = Py_InitModule( ( char* ) pcModule, emptyMethodDefs ); PyObject_SetAttrString( pPythonModule, pTypeObject -> tp_name, ( PyObject* ) pTypeObject ); } end_synchronized}////////////////////////////////////////////////////////////////////////////////PythonInterpreterImpl::PythonInterpreterImpl( ){}////////////////////////////////////////////////////////////////////////////////void PythonInterpreterImpl::invoke( const String& sStatement, const p<OutputStream>& pOutputStream, const p<Directory>& pWorkingDirectory){ synchronized_py { ThreadOutputStreamBinder binder( pOutputStream ); String sWorkingDirectory; const char* pcStatement; if( pWorkingDirectory != 0 ) { Array<String> sParts; sWorkingDirectory = pWorkingDirectory -> getDescriptor( ) -> getFullName( ); sParts = sWorkingDirectory.split( '\\' ); sWorkingDirectory = sParts[0]; for( size_t i = 1; i < sParts.getLength( ); i++ ) { sWorkingDirectory << "\\\\" << sParts[i]; } } if( sWorkingDirectory.getLength( ) > 0 ) { String sSavePath = "import sys\n" "sys.path.append( '" + sWorkingDirectory + "' )\n"; pcStatement = sSavePath; PyRun_SimpleString( ( char* ) pcStatement ); } pcStatement = sStatement; PyRun_SimpleString( ( char* ) pcStatement ); if( sWorkingDirectory.getLength( ) > 0 ) { String sRestorePath = "sys.path.remove( '" + sWorkingDirectory + "' )\n"; pcStatement = sRestorePath; PyRun_SimpleString( ( char* ) pcStatement ); } } end_synchronized}////////////////////////////////////////////////////////////////////////////////NativePythonException::NativePythonException( ): PythonException( fetchError( ) ){}////////////////////////////////////////////////////////////////////////////////String NativePythonException::fetchError( ){ PyObject* pType; PyObject* pValue; PyObject* pTraceback; String sDescription; PyErr_Fetch( &pType, &pValue, &pTraceback ); if( pTraceback != 0 ) {/* PyObject* pStr = PyObject_Str( pTraceback ); if( pStr != 0 ) { sDescription = PyString_AS_STRING( pStr ); Py_DECREF( pStr ); }*/ } if( pValue != 0 ) { PyObject* pStr = PyObject_Str( pValue ); if( pStr != 0 ) { sDescription += PyString_AS_STRING( pStr ); Py_DECREF( pStr ); } } Py_XDECREF( pTraceback ); Py_XDECREF( pValue ); Py_XDECREF( pType ); return sDescription;}////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -