13.07.2015 Views

Proceedings of the 8th Annual Python in Science Conference

Proceedings of the 8th Annual Python in Science Conference

Proceedings of the 8th Annual Python in Science Conference

SHOW MORE
SHOW LESS
  • No tags were found...

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Convert-XY: type-safe <strong>in</strong>terchange <strong>of</strong> C++ and <strong>Python</strong> conta<strong>in</strong>ers for NumPy extensionsCopyThis compound type specifies that <strong>the</strong> str<strong>in</strong>g keys andvector elements be copied but <strong>the</strong> buffer po<strong>in</strong>ter to <strong>the</strong>arrays should be reused. Figure 5 illustrates how thisrecursive <strong>in</strong>stantiation works.DefaultToCPPAction::ActionCopyKeyActionDefaultToCPPAction::ActionActionCopyValueActionDefaultToCPPAction::ActionActionCopyElementActionDefaultToCPPAction Action::ActionActionAllocateCopyCopyFigure 5 The process <strong>of</strong> conversion is deducedat compile time via recursive <strong>in</strong>stantiation <strong>of</strong>DefaultToCPPAction.The process <strong>of</strong> conversion can be overridden by pass<strong>in</strong>gas a template argument a different Action type. Forexample, suppose <strong>the</strong> target BasicImage was allocatedfrom elsewhere (e.g. a special malloc function thatproperly aligns buffers), we can override <strong>the</strong> defaultconversion action (Reuse) so Copy is used as <strong>the</strong>Action <strong>in</strong>stead. The ConvertXY::convert_overridefunction can be used for this purpose:void example(PyObject *x, BasicImage &y) {convert_override(x, y);}Suppose a C++ object y <strong>of</strong> a compound conta<strong>in</strong>er typealready exists, e.g. an object <strong>of</strong> type map. In this case, <strong>the</strong> keys shouldnot be copied but we must ensure that <strong>the</strong> C++ mapconta<strong>in</strong>s exactly <strong>the</strong> same set <strong>of</strong> keys as <strong>the</strong> <strong>Python</strong>dictionary. This is done by first check<strong>in</strong>g that <strong>the</strong> size<strong>of</strong> <strong>the</strong> dictionary is <strong>the</strong> same as <strong>the</strong> std::map and <strong>the</strong>nmak<strong>in</strong>g sure each unique key <strong>in</strong> <strong>the</strong> dictionary is equivalentto some unique key <strong>in</strong> <strong>the</strong> map.The contents <strong>of</strong> a dictionary <strong>of</strong> arrays can be copied<strong>in</strong>to a std::map <strong>of</strong> exist<strong>in</strong>g BasicImage buffers as follows:void example(PyObject *x,map &y) {convert_override(x, y);}The CheckSize simple checks that <strong>the</strong> size <strong>of</strong><strong>the</strong> std::map and <strong>Python</strong> map are equivalent.CheckExists ensures each key <strong>in</strong> <strong>the</strong> <strong>Python</strong> map isalso <strong>in</strong> <strong>the</strong> STL map.Reference count<strong>in</strong>g is automatically handled dur<strong>in</strong>gconversion with PyCXX. In cases where <strong>the</strong> flow <strong>of</strong>execution may return to <strong>Python</strong> after conversion, Py-CXX can be used to ensure objects that are <strong>in</strong> use byC++ rout<strong>in</strong>es don’t get prematurely destroyed.:void example(PyObject *x,BasicImage &y) {// The l<strong>in</strong>e below is safe.convert(x,y);// However, if it can’t be guaranteed that program// control flow will never return to <strong>Python</strong>// for <strong>the</strong> rest <strong>of</strong> this function, use PyCXX’s// Py::Object to <strong>in</strong>crement <strong>the</strong> reference count.Py::Object obj(x);// If <strong>the</strong> flow <strong>of</strong> execution returns to <strong>Python</strong> while// execut<strong>in</strong>g <strong>the</strong> function below, y will always po<strong>in</strong>t// to a valid buffer.compute(y);}The O<strong>the</strong>r Way Around: from C++ to <strong>Python</strong>When convert<strong>in</strong>g from C++ to <strong>Python</strong>, <strong>the</strong> typestructure <strong>of</strong> <strong>the</strong> target <strong>Python</strong> object must beprespecified at compile time (e.g. <strong>the</strong> type <strong>of</strong> <strong>the</strong><strong>Python</strong> object to be created is static). This is notstraightforward s<strong>in</strong>ce <strong>the</strong>re is sometimes more thanone compatible <strong>Python</strong> type for a C++ type. Forexample, an STL vector can be converted to a <strong>Python</strong>list, tuple, or NumPy object array. In Convert-XYthis is deduced with a compile-time-only Structuremetatype deduced by recursive <strong>in</strong>stantiation <strong>of</strong>DefaultTo<strong>Python</strong>Structure::Structure.Figure 6illustrates how DefaultTo<strong>Python</strong>Structureis recursively <strong>in</strong>stantiated to yield a default <strong>Python</strong>target type.To<strong>Python</strong>DefaultStructure::StructureStructurePyDictKeyStructureTo<strong>Python</strong>DefaultStructure::StructureStructurePyStr<strong>in</strong>gNon-term<strong>in</strong>al Structure TypeTerm<strong>in</strong>al Structure TypeExpanded typedefValueStructureTo<strong>Python</strong>DefaultStructure::StructureElementStructurePyListElementStructureDefault::StructureStructurePyArrayPyDictFigure 6 The default <strong>Python</strong> type when convert<strong>in</strong>gfrom C++ to <strong>Python</strong> is deduced by recursive <strong>in</strong>stantiation<strong>of</strong> To<strong>Python</strong>DefaultStructure.As <strong>the</strong> figure illustrates, <strong>the</strong> default type for a <strong>Python</strong>target given a source object that’s an STL map mapp<strong>in</strong>gstr<strong>in</strong>g to vectors <strong>of</strong> images is PyDict. If a tuple is preferredover a list, <strong>the</strong> default structure can be overridenas follows:c○2009, D. Eads, E. Rosten 32

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!