рд╕реА ++ рдФрд░ рдкрд╛рдпрдерди рдХреА рджреЛрд╕реНрддреА рдХреА рдХрд╣рд╛рдиреА рдХреЗ рдЗрд╕ рдЕрдзреНрдпрд╛рдп рдореЗрдВ, Boost.Python рдХрд╛ рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд░реВрдк рд╕реЗ рдмрд╣реБрдд рдХрдо рдЙрдкрдпреЛрдЧ рд╣реЛрдЧрд╛ред рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдХрдордЬреЛрд░ рдмрд┐рдВрджреБ рд╣реИред рд╣рдо рдореВрд▓ рдкрд╛рдпрдерди рдПрдкреАрдЖрдИ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдЬрд╣рд╛рдВ Boost.Python рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред
рдлрд┐рд░ рднреА, Boost.Python рдПрдХ рдРрд╕рд╛ рд╡рд╛рддрд╛рд╡рд░рдг рдмрдирд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ C ++ рд╕реЗ рдЕрдкрд╡рд╛рдж рдПрдХ рдорд╛рдирдХ RuntimeError рдХреЗ рд░реВрдк рдореЗрдВ Python рдореЗрдВ рдЖрддреЗ рд╣реИрдВ, рдФрд░ C ++ рдХрд╛ рдЕрдкрд╡рд╛рдж рдЯрд╛рдЗрдк error_already_set Python рд╕реЗ рд╡рд╛рдкрд╕ рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдХреБрдЫ рдЖ рдЧрдпрд╛ рд╣реИ, рдЗрд╕реЗ рд╕реНрд╡рдпрдВ рдкрдврд╝реЗрдВред " рдФрд░ рдпрд╣рд╛рдВ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдпрд╣ рд╕рд╣реА рд╣реИ рдХрд┐ рд╣рдо рдЕрдкрд╡рд╛рдж рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдШрдЯрд╛рдПрдВ рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рддрд░реНрдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЙрдкрдпреБрдХреНрдд рд╡рд░реНрдЧ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╛рдпрдерди рднрд╛рд╖рд╛ рдХреЗ рд╕реА-рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
рдРрд╕реА рдореБрд╢реНрдХрд┐рд▓реЗрдВ рдХреНрдпреЛрдВ? - рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдкрд╛рдпрдерди рдореЗрдВ, рд╕реА ++ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЕрдкрд╡рд╛рдж рдкрд╛рда рдФрд░ рдЗрд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЯреНрд░реЗрд╕рдмреИрдХ рднреА рдЖрддрд╛ рд╣реИ - рдЕрдкрд╡рд╛рдж рдХреЗ рд╕реНрдерд╛рди рдкрд░ рд╕реНрдЯреИрдХред рдЪрд▓реЛ рдорд╛рдирдХ std рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░реЗрдВ :: рдЗрд╕ рд╕реНрдЯреИрдХрдЯреНрд░реЗрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдереЛрдбрд╝рд╛ рд╕рд╛ рдЕрдкрд╡рд╛рдж, рдФрд░ рд╕рд╛рде рд╣реА рд╣рдо C ++ рдХрдХреНрд╖рд╛рдУрдВ рд╕реЗ рдкрд╛рдпрдерди рдЕрдкрд╡рд╛рдж рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдкрд╡рд╛рдж рдХрдирд╡рд░реНрдЯрд░ рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рд▓рд┐рдЦреЗрдВрдЧреЗред
рдкрд┐рдЫрд▓реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ
1. рдмреВрд╕реНрдЯ.рдкрд╛рдпрдереЙрдиред рдкрд░рд┐рдЪрдпред рдкрд╛рдпрдерди рдореЗрдВ рд╕реА ++ рд░реИрдкрд░ред2. рдмреВрд╕реНрдЯ.рдкрд╛рдпрдереЙрдиред рд╡рд┐рд╢рд┐рд╖реНрдЯ C ++ рдХрдХреНрд╖рд╛рдПрдВ рд░реИрдкрд┐рдВрдЧред3. рдмреВрд╕реНрдЯ.рдкрд╛рдпрдереЙрдиред C ++ рдФрд░ рдкрд╛рдЗрдерди рдХреЗ рдмреАрдЪ рдЯрд╛рдЗрдк рдХрдиреНрд╡рд░реНрдЯрд░реНрд╕ рдмрдирд╛рдирд╛редрдкрд░рд┐рдЪрдп
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЕрдкрд╡рд╛рджреЛрдВ рдХрд╛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкрджрд╛рдиреБрдХреНрд░рдо рд╣реИ рдЬрд┐рд╕реЗ рдЕрдкрд╡рд╛рдж рдХреЛ рд╣реИрдВрдбрд▓ рдХрд░рддреЗ рд╕рдордп рдЖрдкрдХреЛ C ++ рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рд╡рд░реНрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдФрд░ рдкрд╛рдпрдерди рдореЗрдВ рдПрдХ-рдПрдХ-рдПрдХ рддрд░реАрдХреЗ рд╕реЗ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рдЪ рд╣реИ рдпрджрд┐ рдЖрдк рдЬрдЯрд┐рд▓ рдкрд╛рдпрдерди рд╕реНрдХреНрд░рд┐рдкреНрдЯрд┐рдВрдЧ рдХреЗ рд╕рд╛рде C ++ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рддрд░реНрдХ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдпрд╛ рдпрджрд┐ рдЖрдк рдЬрдЯрд┐рд▓ рддрд░реНрдХ рдХреЗ рд╕рд╛рде C ++ рдореЗрдВ рдкрд╛рдпрдерди рдХреЗ рд▓рд┐рдП рдПрдХ рдореЙрдбреНрдпреВрд▓ рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВред рдЬрд▓реНрджреА рдпрд╛ рдмрд╛рдж рдореЗрдВ, рд╣рдо рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдореЗрдВ рдЪрд▓рддреЗ рд╣реИрдВ рдЬреЛ рдкрд╛рдпрдерди рдореЗрдВ C ++ рд╕реЗ рдЖрдпрд╛ рдпрд╛ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрддред
рдмреЗрд╢рдХ, рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдорд╛рдирдХ ++ost.ython рддрдВрддреНрд░ рдПрдХ рдЕрдкрд╡рд╛рдж рдХреЛ C ++ рд╕реЗ рдкрд╛рдпрдерди рдореЗрдВ рдПрдХ RuntimeException рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдкрд╡рд╛рдж рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдкрд╛рда рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реЛрддрд╛ рд╣реИ :: рдХреНрдпрд╛ () рдЖрдкрдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛ред C ++ рдХреА рддрд░рдл, рдЖрдкрдХреЛ рдЯрд╛рдЗрдк рдХрд░реЗрдВ
error_already_set рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝рдиреЗ рдФрд░ рджреЗрд╢реА рдкрд╛рдпрдерди рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рдЕрдкрд╡рд╛рдж рдХреЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рдкрд╛рда рдХреЛ рди рдХреЗрд╡рд▓ рдШрдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рдЯреНрд░реЗрд╕рдмреИрдХ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдкрд╡рд╛рдж рдХрд╛ рдЗрддрд┐рд╣рд╛рд╕ред
рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ рдмрд╛рддреЗрдВ рдкрд╣рд▓реЗред
рдкрд╛рдпрдерди рдореЗрдВ C ++ рд╕реЗ рдПрдХ рдЫреЛрдЯрд╛ рдЕрдкрд╡рд╛рдж рдпрд╛рддреНрд░рд╛
рдЗрд╕рд▓рд┐рдП, рдЖрдкрдиреЗ Boost.Python рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП C ++ рдореЗрдВ рдПрдХ рдореЙрдбреНрдпреВрд▓ рд▓рд┐рдЦрд╛, рдЗрд╕реЗ рдирд┐рдпрдорд┐рдд
рдЖрдпрд╛рдд рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╛рдпрдерди рдХреЛрдб рдореЗрдВ рдЬреЛрдбрд╝рд╛
, рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдпрд╛ рд╡рд┐рдзрд┐рдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рд░реИрдкрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ C ++ рдХреЛрдб рдореЗрдВ рд╕рдмрд╕реЗ рдЖрдо рдЕрдкрд╡рд╛рдж рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ
рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкрд╛рдпрдерди рдХреЛрдб рдореЗрдВ, рдЖрдкрдХреЛ рдЕрдкрд╡рд╛рдж рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдкрд╛рда рдХреЗ рд╕рд╛рде рдПрдХ RuntimeException рдорд┐рд▓реЗрдЧреА: рдХреНрдпрд╛ () рдЕрдЧрд░ рдпрд╣ рдЕрдкрд╡рд╛рдж std :: рдЕрдкрд╡рд╛рдж рд╕реЗ рдлреЗрдВрдХрд╛ рдЧрдпрд╛ рд╣реИред
рдпрджрд┐ рдЖрдк рд╕рдВрддреБрд╖реНрдЯ рд╣реИрдВ рдХрд┐ рдЖрдкрдХреЛ рдЕрдкрд╡рд╛рдж рдкрд╛рда рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХреБрдЫ рднреА рдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрдЧрд╛, рддреЛ рдЖрдк рдХреБрдЫ рдФрд░ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрджрд┐ рдЖрдкрдХреЛ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдПрдХ рд╕рдЦреНрддреА рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╡рд░реНрдЧ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдереЛрдбрд╝рд╛ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, Boost.Python, C ++ рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рджреЗрд╢реА рдкреЗрди рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рдЕрдкрдиреЗ рдЕрдиреБрд╡рд╛рдж рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдпрд╣ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: рдореЙрдбреНрдпреВрд▓ рдШреЛрд╖рдгрд╛ рд╕рдорд╛рд░реЛрд╣ рдореЗрдВ, рдЯреЗрдореНрдкрд▓реЗрдЯ рдлрд╝рдВрдХреНрд╢рди рдмреВрд╕реНрдЯ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ :: python ::
register_exception_translator <T, F> (F), рдЬрд╣рд╛рдВ C C ++ рдореЗрдВ рдЕрдкрд╡рд╛рдж рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ, рдФрд░ F рд╡рд╣ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдкрд╡рд╛рдж рдХрд╛ рд╕рдВрджрд░реНрдн рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдХреИрд╕реЗ рдЗрд╕ рддрд░рд╣, рдкрд╛рдпрдерди рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╛рд╣рд░реА рдХреЛрдб рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рдЕрдкрдиреЗ рдХрд░реНрддрд╡реНрдп рдХреЛ рдкреВрд░рд╛ рдХрд░рдирд╛ред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ:
class error : public exception { ... }; ... void translate_error( error const& ); ... BOOST_PYTHON_MODULE( ... ) { ... register_exception_translator<error>( translate_error ); } ... void translate_error( error const& e ) { PyErr_SetString( PyExc_Exception, e.what() ); }
рдпрд╣рд╛рдБ рд╣рдордиреЗ рдкрд╛рдпрдерди рдореЗрдВ рдирд┐рд░реНрдорд┐рдд рдкреНрд░рдХрд╛рд░ рдЕрдкрд╡рд╛рдж рдХреЗ рдПрдХ рдорд╛рдирдХ рдЕрдкрд╡рд╛рдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рдмрд┐рд▓реНрдХреБрд▓ рдХрд┐рд╕реА рднреА рдЕрдкрд╡рд╛рдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: PyObject * рдХреЛ
рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдпрд╛рдд рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬреБрдбрд╝рд╛ рдПрдХ
рдорд╛рдирдХ , рдмрд╛рд╣рд░реА
:: ptr () рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЖрдкрдХрд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдмрдирд╛рдпрд╛ рд╣реБрдЖ
PyErr_NewException рдХреЗ рд╕реНрдерд╛рди рдкрд░ред
рдкреВрд░реНрдгрддрд╛ рдХреА рдЦрд╛рддрд┐рд░, рдЖрдЗрдП рдХреБрдЫ рдФрд░ рд╡рд░реНрдЧ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ ZeroDivisionError рдФрд░ ValueError рдХреЗ рдПрдирд╛рд▓реЙрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдкреВрд░реНрдг рдЦреБрд╢реА рдХреЗ рд▓рд┐рдП рд╣рдо рдЙрдиреНрд╣реЗрдВ рдХреНрд░рдорд╢рдГ рдЕрдкрдиреА рддреНрд░реБрдЯрд┐ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ, рдЙрдиреНрд╣реЗрдВ рдХреНрд░рдорд╢рдГ рд╢реВрдиреНрдп_рдбрд┐рд╡реАрдЬрд╝рди -рд░рд┐рдпрд░ рдФрд░ value_error рдХрд╣реЗрдВрдЧреЗ:
class error : public exception { public: error(); error( string const& message ); error( string const& message, string const& details ); virtual const char* what() const; virtual string const& get_message() const; virtual string const& get_details() const; virtual const char* type() const; private: string m_message; string m_details; }; class value_error : public error { public: value_error(); value_error( string const& message ); value_error( string const& message, string const& details ); virtual const char* type() const; }; class zero_division_error : public error { public: zero_division_error(); zero_division_error( string const& message ); zero_division_error( string const& message, string const& details ); virtual const char* type() const; };
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдЯреНрд░реЗрд╕рдмреИрдХ рд╕рд╣реЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ Python рд╕реЗ C ++ рдХреЗ рд░рд╛рд╕реНрддреЗ рдореЗрдВ
m_details рдлрд╝реАрд▓реНрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдФрд░ рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ () рд╡рд┐рдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рд╕рд░рд▓ рдФрд░ рд╕реНрдкрд╖реНрдЯ рдкрджрд╛рдиреБрдХреНрд░рдоред
рдЪрд▓реЛ рд╣рдорд╛рд░реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд╛рдпрдерди рдореЗрдВ рдЕрдиреБрд╡рд╛рджрдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВ:
void translate_error( error const& ); void translate_value_error( value_error const& ); void translate_zero_division_error( zero_division_error const& ); ... BOOST_PYTHON_MODULE( ... ) { ... register_exception_translator<error>( translate_error ); register_exception_translator<value_error>( translate_value_error ); register_exception_translator<zero_division_error>( translate_zero_division_error ); } ... void translate_error( error const& e ) { PyErr_SetString( PyExc_Exception, e.what() ); } void translate_value_error( value_error const& e ) { PyErr_SetString( PyExc_ValueError, e.what() ); } void translate_zero_division_error( zero_division_error const& e ) { PyErr_SetString( PyExc_ZeroDivisionError, e.what() ); }
рдЦреИрд░, рдЬреЛ рдХреБрдЫ рднреА рд╣реИ рд╡рд╣ C ++ рдХреА рдУрд░ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ, рдЬреЛ рдЗрди рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдлреЗрдВрдХ рджреЗрдВрдЧреЗ:
double divide( double a, double b ) { if( abs( b ) < numeric_limits<double>::epsilon() ) throw zero_division_error(); return a / b; } double to_num( const char* val ) { double res; if( !val || !sscanf( val, "%LG", &res ) ) throw value_error(); return res; } void test( bool val ) { if( !val ) throw error( "Test failure.", "test" ); }
рдХреНрдпреЛрдВ рдирд╣реАрдВ, рдпреЗ рдлрд╝рдВрдХреНрд╢рди рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрджрддрд░ рдирд╣реАрдВ рд╣реИрдВ рдФрд░ рдареАрдХ рдЙрд╕реА рддрд░рд╣ рдлреЗрдВрдХрддреЗ рд╣реИрдВ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдПред
рдЙрдиреНрд╣реЗрдВ рд▓рдкреЗрдЯреЗрдВ:
... BOOST_PYTHON_MODULE( python_module ) { register_exception_translator<error>( translate_error ); register_exception_translator<value_error>( translate_value_error ); register_exception_translator<zero_division_error>( translate_zero_division_error ); def( "divide", divide, args( "a", "b" ) ); def( "to_num", to_num, args( "val" ) ); def( "test", test, args( "val" ) ); } ...
рдЦреИрд░, рд╣рдо рдЕрдкрдиреЗ рдореЙрдбреНрдпреВрд▓ рдХрд╛
рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╣реИрдВ,
рдЖрдпрд╛рдд python_module рдирд┐рд╖реНрдкрд╛рджрд┐рдд
рдХрд░рддреЗ рд╣реИрдВ , рдЖрд╡рд╢реНрдпрдХ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдЕрдкрд╡рд╛рдж рдорд┐рд▓рддреЗ рд╣реИрдВ (рдкрд╛рдпрдерди 3.x рд╕реНрдХреНрд░рд┐рдкреНрдЯ):
import python_module as pm try: res = pm.divide( 1, 0 ) except ZeroDivisionError: print( "ZeroDivisionError - OK" ) except Exception as e: print( "Expected ZeroDivisionError, but exception of type '{t}' with text: '{e}'".format(t=type(e),e=e) ) else: print( "Expected ZeroDivisionError, but no exception raised! Result: {r}".format(r=res) ) try: res = pm.to_num( 'qwe' ) except ValueError: print( "ValueError - OK" ) except Exception as e: print( "Expected ValueError, but exception of type '{t}' with text: '{e}'".format(t=type(e),e=e) ) else: print( "Expected ValueError, but no exception raised! Result: {r}".format(r=res) ) try: res = pm.test( False ) except Exception as e: if type(e) is Exception: print( "Exception - OK" ) else: print( "Exception of type '{t}', expected type 'Exception', message: '{e}'".format(t=type(e),e=e) ) else: print( "Expected Exception, but no exception raised! Result: {r}".format(r=res) )
рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЖрдЙрдЯрдкреБрдЯ:
ZeroDivisionError - рдареАрдХ рд╣реИ
ValueError - рдареАрдХ рд╣реИ
рдЕрдкрд╡рд╛рдж - рдареАрдХ рд╣реИ
рдЕрднреА рддрдХ рддреЛ рдЕрдЪреНрдЫрд╛ рд╣реИред рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛ рдореЗрдВ рдЪрд▓рддреЗ рд╣реИрдВред
рдкрд╛рдпрдерди рд╕реЗ рд╕реА ++ рдХреЗ рд░рд╛рд╕реНрддреЗ рд╣рдорд╛рд░реЗ рдЕрдкрд╡рд╛рдж рдХрд╛ рд░реЛрдорд╛рдВрдЪ
рдЖрдЗрдП рдПрдХ рдЕрд▓рдЧ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЕрдкрд╡рд╛рджреЛрдВ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ, рдФрд░ рд╣рдо рдЙрдирдХреЗ рд╕рд╛рде рдПрдХ рдЕрд▓рдЧ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдЬреБрдбрд╝реЗ
error_types рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░реЗрдВрдЧреЗред рд╣рдо рдЕрдЬрдЧрд░ рдХреЗ рд▓рд┐рдП рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдЕрд▓рдЧ рд╕реЗ
python_module рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдХрд░реЗрдВрдЧреЗред
рдЕрдм рдЪрд▓реЛ C ++ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рд╣рдо рдкрд╛рдпрдерди рд╕реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ
рдкрдХрдбрд╝реЗрдВрдЧреЗ , рдЗрд╕реЗ
catch_exception рдХрд╣рддреЗ рд╣реИрдВред
рдЬрд░реВрд░рдд рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдЖрдпрд╛рдд ("python_module") рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рд╣реИ, рдлрд┐рд░ attr ("divide"), attr ("to_num"), attr ("рдкрд░реАрдХреНрд╖рдг") рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдореЙрдбреНрдпреВрд▓ рдлрд╝рдВрдХреНрд╢рди рддрдХ рдкрд╣реБрдВрдЪреЗрдВред рд╣рдо рдЙрдиреНрд╣реЗрдВ рдХреЙрд▓ рдХрд░реЗрдВрдЧреЗ, рд╡реЗ C ++ рдХреЛрдб рд╕реНрддрд░ рдкрд░ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдЙрдард╛рдПрдВрдЧреЗ, рдкрд╛рдпрдерди рдЗрдВрдЯрд░рдкреНрд░реЗрдЯрд░ рдореЗрдВ рдЬрд╛рдПрдВрдЧреЗ рдФрд░ рдлрд┐рд░ C ++ рдПрдкреНрд▓рд┐рдХреЗрд╢рди
рдореЗрдВ рдлреЙрд░рд╡рд░реНрдб рдХрд░реЗрдВрдЧреЗ, error_already_set рдЕрдкрд╡рд╛рдж рдХреЛ
рдлреЗрдВрдХрддреЗ рд╣реБрдП - Boost.Python рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЕрдкрд╡рд╛рдж рдХреЗрд╡рд▓ рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдкреНрд░рдХрд╛рд░
error_already_set рдХрд╛ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ, рдХреЗрд╡рд▓ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝рдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЗрд╕ рддрд░рд╣ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
catch( error_already_set const& ) { PyObject *exc, *val, *tb; PyErr_Fetch( &exc, &val, &tb ); PyErr_NormalizeException( &exc, &val, &tb ); handle<> hexc(exc), hval( allow_null( val ) ), htb( allow_null( tb ) ); throw error( extract<string>( !hval ? str( hexc ) : str( hval ) ) ); }
рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рд╣рдореЗрд╢рд╛ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдкрд╡рд╛рдж рдорд┐рд▓рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХрдо рд╕реЗ рдХрдо рд╣рдо рдЕрдкрд╡рд╛рдж рдХрд╛ рдкрд╛рда рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╣рдореЗрдВ exc рд╡реИрд░рд┐рдПрдмрд▓ рдореЗрдВ рдЕрдкрд╡рд╛рдж рдХрд╛ рдкреНрд░рдХрд╛рд░ рдорд┐рд▓рддрд╛ рд╣реИ, рдЕрдкрд╡рд╛рдж рдСрдмреНрдЬреЗрдХреНрдЯ рд╡реИрд▓ рд╡реИрд░рд┐рдПрдмрд▓ рдореЗрдВ рднреА рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ tb рд╡реЗрд░рд┐рдПрдмрд▓ рдореЗрдВ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕реНрдЯреИрдХ рдХреЗ рд╕рд╛рде рднреА рд╣реЛрддрд╛ рд╣реИред рдпрджрд┐ рдЬреАрд░реЛ рдбрд┐рд╡рд┐рдЬрд╝рди рдПрдЕрд░рд░ рдпрд╛ рд╡реИрд▓реНрдпреВрдЕрд░рд░ рдХреНрд░рдорд╢рдГ рдЖрддреЗ рд╣реИрдВ, рддреЛ рд╢реВрдиреНрдп_рдбрд┐рд╡рд┐рдЬрд╝рди_рд░реЛрд░ рдФрд░ рд╡реЗрд▓реНрдпреВ_рд░реЛрд░ рдХреЛ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддреЗ рд╣реИрдВред
рдЗрд╕реЗ рд░реЛрдХреЛ! рд╣рд░ рдХреЛрдИ рдпрд╣ рдирд╣реАрдВ рд╕рдордЭрддрд╛ рд╣реИ рдХрд┐ рдпреЗ рджреЛ рдХрд╛рд░реНрдп рдХреНрдпрд╛ рд╣реИрдВ, рдХреНрдпреЛрдВ рд╕рдм рдХреБрдЫ PyObject * рд╣реИ, C-API рдореЗрдВ рдЕрдкрд╡рд╛рдж рдХрд╣рд╛рдВ рд╣реИрдВ рдпрджрд┐ C рдореЗрдВ рдХреЛрдИ рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рджреЗрдВред
рд╣рд╛рдВ, рд╢реБрджреНрдз рд╕реА рдореЗрдВ рдХреЛрдИ рдЕрдкрд╡рд╛рдж рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдкрд╛рдпрдерди рдореЗрдВ рд╡реЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХрд╛ рдПрдкреАрдЖрдИ рдЕрдкрд╡рд╛рдж рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдЦреАрдВрдЪрдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдкрд╛рдпрдерди рд╕реА-рдПрдкреАрдЖрдИ рдореЗрдВ, рд╕рднреА рдорд╛рди рдФрд░ рдкреНрд░рдХрд╛рд░, рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд▓рдЧрднрдЧ рд╕рдм рдХреБрдЫ, рдХреЛ PyObject * рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЯрд╛рдЗрдк T рдХрд╛ рдПрдХ рдЕрдкрд╡рд╛рдж E рдкреНрд░рдХрд╛рд░ PyObject * рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рд╣реИ, рд╣рдо PyObject * рдХреЛ рдЯреНрд░реЗрд╕рдмреИрдХ рд╕реЗрд╡ рд╕реНрдЯреИрдХ рдореЗрдВ рднреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдЕрдкрд╡рд╛рдж рд╣реБрдЖред ред
PyErr_Fetch рдЙрд╕ рдЕрдкрд╡рд╛рдж рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА
рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рд╣реБрдЖ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдЕрдкрд╡рд╛рдж рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдпрджрд┐ рдЖрдк рдЖрдВрддрд░рд┐рдХ рдЯрдкрд▓ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ)
PyErr_NormalizeException рдХреЗ рд╕рд╛рдеред
рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдХреНрд░рдорд╢рдГ PyObject * рдкреНрд░рдХрд╛рд░ рдХреЗ рддреАрди рдореВрд▓реНрдпреЛрдВ рдХреЛ рднрд░ рджреЗрдВрдЧреЗ: рдЕрдкрд╡рд╛рдж рдХрд╛ рдЕрдкрд╡рд╛рдж рд╡рд░реНрдЧ, рдЙрджрд╛рд╣рд░рдг (рдСрдмреНрдЬреЗрдХреНрдЯ) рдФрд░ рд╕реНрдЯреИрдХ (рдЯреНрд░реЗрд╕рдмреИрдХ) рдХреЛ рдЙрд╕ рд╕рдордп рдмрдЪрд╛рдпрд╛ рдЧрдпрд╛ рдЬрдм рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, Boost.Python рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рд╣рдо PyObject * рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдореЗрдВ :: python ::
рд╣реИрдВрдбрд▓ <> рдХреЛ рд▓рдкреЗрдЯрддреЗ рд╣реИрдВ, рдЬреЛ Boost.Python рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдХрд┐рд╕реА рднреА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рд╣реИ, рд╣рдореЗрдВ рдмрд╕ python ::
str рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред Boost.Python рдореЗрдВ рдПрдХ рдПрдирд╛рд▓реЙрдЧ рдЕрдЬрдЧрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо C ++ рднрд╛рд╖рд╛ рдХреЗ рдорд╛рдирдХ рджреЗрд╢реА рд╕реНрдЯреНрд░рд┐рдВрдЧ std :: string рдХреЛ рдмрдврд╝рд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рд╡рд╛рдВрдЫрд┐рдд рд╣реИ, рддреЛ рдЖрдк рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд╕реНрдЯ рдЪрд╛рд░ * рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдкрд╣рд▓реЗ рджреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде, рд╕рдмрдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рд╡реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП reducible рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЯреНрд░реЗрд╕рдмреИрдХ рдХреЗ рд╕рд╛рде рдЖрдкрдХреЛ рдЕрднреА рднреА рдПрдХ рдкрдардиреАрдп рд░реВрдк рдореЗрдВ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред
рдЯреНрд░реЗрд╕рдмреИрдХ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рд╣реИ, рд╣рдорд╛рд░реЗ рддреАрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ
format_exception рдлрд╝рдВрдХреНрд╢рди рд╕реЗ
рдЧреБрдЬрд░рдирд╛ ред рдЯреНрд░реЗрд╕рдмреИрдХ.рдлреЙрд░реНрдордЯ_рдПрдХреНрд╕рд╕реЗрдкреНрд╢рди (рдПрдХреНтАНрд╕, рд╡реИрд▓, рдЯреАрдмреА) рдлрд╝рдВрдХреНрд╢рди рд╣рдореЗрдВ рдорд╛рдирдХ рдкрд╛рдпрдерди рднрд╛рд╖рд╛
рд╕реВрдЪреА рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рдПрдХ рд╕рд░рдгреА рд▓реМрдЯрд╛рдПрдЧрд╛, рдЬреЛ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд░реВрдк рд╕реЗ рдПрдХ рдмрдбрд╝реА рдореЛрдЯреА рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдорд┐рд▓рддреА рд╣реИред
C ++ рдХреА рддрд░рдл, Boost.Python рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
... format_exception = import( "traceback" ).attr( "format_exception" ); return extract<string>( str( "" ).join( format_exception( exc, val, tb ) ) ); }
рдЖрдк рдПрдХ рдЕрдкрд╡рд╛рдж рд╕реЗ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдп рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХреЙрд▓рд┐рдВрдЧ рдЖрдпрд╛рдд () рд╣рд░ рдмрд╛рд░ рдПрдХ рдорд╣рдВрдЧреА рдХреЙрд▓ рдХрд╛ рдХрд╛рд░рдг рдмрдиреЗрдЧреА, рдЗрд╕рд▓рд┐рдП рдЖрдпрд╛рдд рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдСрдмреНрдЬреЗрдХреНрдЯ ("рдЯреНрд░реЗрд╕рдмреИрдХ") .attr ("format_exception") рдПрдХ рдЕрд▓рдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИ, рд╣рдореЗрдВ рднреА рдмрдЪрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЖрдпрд╛рдд рдкрд░рд┐рдгрд╛рдо ("python_module")ред рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рдЗрд╕реЗ Py_Initialize () рдФрд░ Py_Finalize () рдХреЗ рдмреАрдЪ рдХрд╣реАрдВ рдФрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдлрд┐рд░ рдРрд╕реЗ рд╡реИрд░рд┐рдПрдмрд▓ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЧрд▓рдЯрди рдлреАрд▓реНрдб рд╕реЗ рдмреЗрд╣рддрд░ рдХреБрдЫ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред
рд╕рд┐рдВрдЧрд▓рдЯрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╛рдпрдерди рдПрдкреАрдЖрдИ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ
рддреЛ, рдЪрд▓реЛ рдПрдХ рд╕рд┐рдВрдЧрд▓рдЯрди рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЬрдЯрд┐рд▓ рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдХреЛрдб рдХреЛ рдереЛрдбрд╝рд╛ рд╕рд░рд▓ рдХрд░реЗрдЧрд╛ рдФрд░ рдЖрдкрдХреЛ рджреБрднрд╛рд╖рд┐рдпрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛, рд╕рднреА рд╕рд╣рд╛рдпрдХ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдмрдЪрд╛рдПрдЧрд╛ рдФрд░ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкреВрд░рд╛ рдХрд░реЗрдЧрд╛:
class python_interpreter { public: static double divide( double, double ); static double to_num( string const& ); static void test( bool ); static string format_error( handle<> const&, handle<> const&, handle<> const& ); private: object m_python_module; object m_format_exception; python_interpreter(); ~python_interpreter(); static python_interpreter& instance(); object& python_module(); string format_error( object const&, object const&, object const& ); };
рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдЗрдВрдЯрд░рдкреНрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░реЗрдЧрд╛, рдФрд░ рдбрд┐рд╕реНрдЯреНрд░рдХреНрдЯрд░ рд╕реНрдЯреЛрд░ рдХрд┐рдП рдЧрдП рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЛ рд╕рд╛рдлрд╝ рдХрд░реЗрдЧрд╛ рдФрд░ рдЗрдВрдЯрд░рдкреНрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рдбреА-рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░реЗрдЧрд╛, python_module рдФрд░ format_error рд╡рд┐рдзрд┐рдпрд╛рдБ рдПрдХ рд╣реА рдмрд╛рд░ рд╕рдВрдмрдВрдзрд┐рдд рдореЙрдбреНрдпреВрд▓реНрд╕ рдХреЛ рдЗрдореНрдкреЛрд░реНрдЯ рдХрд░рддреА рд╣реИрдВ:
python_interpreter::python_interpreter() { Py_Initialize(); } python_interpreter::~python_interpreter() { m_python_module = object(); m_format_exception = object(); Py_Finalize(); } double python_interpreter::divide( double a, double b ) { return extract<double>( instance().python_module().attr("divide")( a, b ) ); } double python_interpreter::to_num( string const& val ) { return extract<double>( instance().python_module().attr("to_num")( val ) ); } void python_interpreter::test( bool val ) { instance().python_module().attr("test")( val ); } string python_interpreter::format_error( handle<> const& exc, handle<> const& msg, handle<> const& tb ) { return instance().format_error( object(exc), object(msg), object(tb) ); } python_interpreter& python_interpreter::instance() { static python_interpreter single; return single; } object& python_interpreter::python_module() { if( m_python_module.is_none() ) m_python_module = import( "python_module" ); return m_python_module; } string python_interpreter::format_error( object const& exc, object const& val, object const& tb ) { if( m_format_exception.is_none() ) m_format_exception = import( "traceback" ).attr( "format_exception" ); return extract<string>( str( "" ).join( m_format_exception( exc, val, tb ) ) ); }
рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рд╣рдореЗрдВ рдХрд┐рд╕реА рднреА C ++ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рддреИрдпрд╛рд░-рдирд┐рд░реНрдорд┐рдд рддрдВрддреНрд░ рд▓рд╛рдЧреВ рд╣реИ рдЬреЛ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рдПрдХ рд╕рдореВрд╣ рдХреЗ рд╕рд╛рде рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рдпрдерди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
рдпрд╣ рд╣рдорд╛рд░реЗ рдЕрдкрд╡рд╛рдж рддрдВрддреНрд░ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ!
рдкрд╛рдпрдерди рд╕реЗ C ++ рдореЗрдВ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рдЕрдиреБрд╡рд╛рдж рдХреЗ рд▓рд┐рдП рддрдВрддреНрд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг
рдЖрдЗрдП рдПрдХ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдп рдХрд░реЗрдВ:
void rethrow_python_exception() { PyObject *exc, *val, *tb; PyErr_Fetch( &exc, &val, &tb ); PyErr_NormalizeException( &exc, &val, &tb ); handle<> hexc(exc), hval( allow_null( val ) ), htb( allow_null( tb ) ); string message, details; message = extract<string>( !hval ? str( hexc ) : str( hval ) ); details = !tb ? extract<string>( str( hexc ) ) : python_interpreter::format_error( hexc, hval, htb ); if( PyObject_IsSubclass( exc, PyExc_ZeroDivisionError ) ) throw zero_division_error( message, details ); else if( PyObject_IsSubclass( exc, PyExc_ValueError ) ) throw value_error( message, details ); else throw error( message, details ); }
рдлрд┐рд░ рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рддрдВрддреНрд░ рдирд┐рдореНрди рд╕реНрдХреАрдо рдореЗрдВ рдШрдЯрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреИрд╕реЗ рд╡рд┐рднрд╛рдЬрди рдХреЗ рд▓рд┐рдП:
try { try { python_interpreter::divide( 1, 0 ); } catch( error_already_set const& ) { rethrow_python_exception(); } } catch( error const& e ) { output_error( e ); }
рдпрд╣рд╛рдБ output_error рд╕рдмрд╕реЗ рд╕рд░рд▓ рдХрд╛рд░реНрдп рд╣реИ рдЬреЛ рдЕрдкрд╡рд╛рдж рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрд░рд╣:
void output_error( error const& e ) { cerr << "\nError type: " << e.type() << "\nMessage: " << e.get_message() << "\nDetails: " << e.get_details() << endl; }
рдпрд╣рд╛рдВ, рд╡рд░реНрдЪреБрдЕрд▓ рд╡рд┐рдзрд┐ рдкреНрд░рдХрд╛рд░ (), рдЬрд┐рд╕реЗ рд╣рдордиреЗ рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рддреНрд░реБрдЯрд┐ рдореЗрдВ рдкреЗрд╢ рдХрд┐рдпрд╛ рдерд╛, рдХрд╛рдо рдореЗрдВ рдЖрдпрд╛ред
рд╣рдо to_num рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдЕрдиреБрднрд╛рдЧ рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рднреА рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдЖрддрд╛ рд╣реИ рдпрджрд┐ рд╣рдо рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╛рдпрдерди рдореЗрдВ "1/0" рд▓рд╛рдЗрди рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
try { try { exec( "1 / 0" ); } catch( error_already_set const& ) { rethrow_python_exception(); } } catch( error const& e ) { output_error( e ); }
рд▓реЙрдиреНрдЪ рд╣реЛ рд░рд╣рд╛ рд╣реИ ...
рдЖрдЙрдЯрдкреБрдЯ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:
рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░: zero_division_error
рд╕рдВрджреЗрд╢: рд╢реВрдиреНрдп рд╕реЗ рд╡рд┐рднрд╛рдЬрди!
рд╡рд┐рд╡рд░рдг: <рд╡рд░реНрдЧ 'ZeroDivisionError'>
рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░: value_error
рд╕рдВрджреЗрд╢: рдЕрдиреБрдЪрд┐рдд рдореВрд▓реНрдп!
рд╡рд┐рд╡рд░рдг: <рд╡рд░реНрдЧ 'ValueError'>
рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░: рддреНрд░реБрдЯрд┐
рд╕рдВрджреЗрд╢: рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдлрд▓рддрд╛ред
рд╡рд┐рд╡рд░рдг: <рд╡рд░реНрдЧ 'рдЕрдкрд╡рд╛рдж'>
рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░: zero_division_error
рд╕рдВрджреЗрд╢: рд╢реВрдиреНрдп рд╕реЗ рд╡рд┐рднрд╛рдЬрди
рд╡рд┐рд╡рд░рдг: рдЯреНрд░реЗрд╕рдмреИрдХ (рд╕рдмрд╕реЗ рд╣рд╛рд▓рд┐рдпрд╛ рдХреЙрд▓ рдЕрдВрддрд┐рдо):
ZeroDivisionError рдореЗрдВ рдлрд╛рдЗрд▓ "", рд▓рд╛рдЗрди 1, рд╢реВрдиреНрдп рд╕реЗ рд╡рд┐рднрд╛рдЬрди
рдЙрдкрд╕рдВрд╣рд╛рд░
рдХреБрд▓: рд╣рдореЗрдВ рдкрд╛рдпрдерди рд╕реЗ рд╕реА ++ рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рдЕрдкрд╡рд╛рдж рдХреЗ рд▓рд┐рдП рдПрдХ-рд╕реЗ-рдПрдХ рд░реВрдкрд╛рдВрддрд░рдг рддрдВрддреНрд░ рдорд┐рд▓рд╛ред
рдорд╛рдЗрдирд╕ рддреБрд░рдВрдд рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ - рдпреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рдВрд╕реНрдерд╛рдПрдВ рд╣реИрдВ рдЬреЛ рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рдмрд┐рд▓реНрдХреБрд▓ рдЕрд╕рдВрдмрдВрдзрд┐рдд рд╣реИрдВред рдЗрд╕рдХрд╛ рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ C ++ рдХреНрд▓рд╛рд╕ рдХреЛ рдкрд╛рдпрдерди рд╕реЗ рдПрдХ рдХреНрд▓рд╛рд╕ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдирд╣реАрдВ рд▓рд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рди рд╣реА рдЗрд╕рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХреЛрдИ рджреВрд╕рд░рд╛ рд░рд╛рд╕реНрддрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдкрд╛рдпрдерди рдХреЗ рд▓рд┐рдП C ++ рд╡рд░реНрдЧ рдХреЗ рд░реИрдкрд░ рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рдЕрдкрд╡рд╛рдж рд╡рд░реНрдЧ рдХреЛ "рдПрдирдХреИрдкреНрд╕реБрд▓реЗрдЯ" рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрднреА рднреА рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд░реНрдЧ рд╣реЛрдВрдЧреЗ рдЬреЛ рдмрд╕ рдЕрдкрдиреА рднрд╛рд╖рд╛ рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рд▓реЛрдЧреЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛрддреЗ рд╣реИрдВред
рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ C ++ рдореЗрдВ рдЕрдкрд╡рд╛рджреЛрдВ рдХрд╛ рдПрдХ рдЬрдЯрд┐рд▓ рдкрджрд╛рдиреБрдХреНрд░рдо рд╣реИ, рддреЛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдПрдХ рдЕрд▓рдЧ .py рдореЙрдбреНрдпреВрд▓ рдореЗрдВ
Pythr рдореЗрдВ рдПрдХ рдПрдирд╛рд▓реЙрдЧ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐
PyErr_NewException рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ
рдмрдирд╛рдирд╛ рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдХрд╣реАрдВ рдкрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛ рдмрд╣реБрдд рдорд╣рдВрдЧрд╛ рд╣реИ рдФрд░ рдХреЛрдб рдореЗрдВ рдкрдардиреАрдпрддрд╛ рдирд╣реАрдВ рдЬреЛрдбрд╝реЗрдЧрд╛ред
рдореИрдВ рдЖрдкрдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдирддрд╛, рд▓реЗрдХрд┐рди рдЬрдм Boost.Python рдХреЛ рдЕрдкрд╡рд╛рджреЛрдВ рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЕрдиреБрд╡рд╛рджрдХ рдорд┐рд▓рддрд╛ рд╣реИ, рдпрд╛ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдореБрдЭреЗ рдмрд╣реБрдд рдЦреБрд╢реА рд╣реЛрддреА рд╣реИ :: рдЕрдЬрдЧрд░ :: рдкрд╛рдпрдерди рд╡рд░реНрдЧ рд╕реЗ рдПрдХ рд░реИрдкрд░ рдХреЛ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдзрд╛рд░ред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, Boost.Python рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ, рд▓реЗрдХрд┐рди C ++ рдХреА рдУрд░ рд╕реЗ рдкрд╛рдпрдерди рдХреЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреЗ рд╕рдордп рдпрд╣ рдкрд╣рд▓реВ рд░рдХреНрддрд╕реНрд░рд╛рд╡реА рдЬреЛрдбрд╝ рджреЗрддрд╛ рд╣реИред рдЕрдиреБрд╡рд╛рдж рд╕рдорд╛рд░реЛрд╣ рдХреЗ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╛рдпрдерди рдореЗрдВ рдЕрдиреБрд╡рд╛рдж register_exception_translator <E, F> (F) рдХрд╛рдлреА рд╕рдлрд▓ рджрд┐рдЦрддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ C ++ рдореЗрдВ рдЯрд╛рдЗрдк рдП рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрд╛рдпрдерди рдкрдХреНрд╖ рдкрд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдмреА рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХрдо рд╕реЗ рдХрдо рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗред
рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдпрд╣ рд╡рд░реНрдгрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ error_already_set рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рд╣реИ, рдЖрдк
рдкрд╛рдпрдерди рд╕реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП
рдкрд╛рдпрдерди рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рдиреБрд╕реНрдЦрд╛ рдЪреБрди рд╕рдХрддреЗ рд╣реИрдВред
рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рд▓рд┐рдВрдХ
рдпрд╣рд╛рдВ (~ 223 KB) рд╣реИ ред MSVS v11 рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмреВрд╕реНрдЯ 1.52 рдФрд░ рдкрд╛рдпрдерди 3.3 x64 рдХреЗ рд╕рд╛рде рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдЙрдкрдпреЛрдЧреА рд▓рд┐рдВрдХ
рдкрд┐рд╡рд┐рдХреА - рд╕реА ++ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрдирд╛рдкрд╛рдпрдерди рд╕реА-рдПрдкреАрдЖрдИ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧрдкрд╛рдпрдерди рдореЗрдВ рд╕реА ++ рдЕрдкрд╡рд╛рдж рдЕрдиреБрд╡рд╛рджрдХ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВ