Pink 0.9
Namespaces

ui_make_function.hpp File Reference

This is a helper function for exporting Pink C functions in Python. Note that this template file is rarely used directly and is called by the UI_WRAP_FUNCTION macro. More...

Namespaces

namespace  pink

Detailed Description

This is a helper function for exporting Pink C functions in Python. Note that this template file is rarely used directly and is called by the UI_WRAP_FUNCTION macro.

Note

For debugging macro definitions you can use the

  g++ -E -P file.cpp -o file_pp.cpp
  

commands, which outputs the source code after preprocessing. Also

  astyle -A3 -z2 -k1 -s2 -j file_pp.cpp 
  

Indents the preprocessed code and inserts lot's of newlines, which improoves very much the readability of the code.

Exporting functions from C

For exporting functions from Pink you should make them follow the Conventions for developing Pink operators.

You may use printf and you may call exit(1) if there's an error. type_k can be any type that python recognizes (int, float, ...) and xvimage* The return value is 1 on success and 0 otherwise. To export this function you should include a function call in pypink.cpp of the form

  def( 
    "function's name in Python",
    &make_function<char_image, T1, T2, ..., Tn, &pink_c_function>,
    (arg("argument 1 name"), arg("argument 2 name"), ..., arg(argument n name) )
    doc__my_c_function__c__
  )

make_function is a template. In the first parameter you specify the image type. Second, you specify the types of the parameters and last you put the pointer to your Pink function.

Example:

  def( "ptisolated",
       &make_function<char_image, int, &lptisolated>,
       ( arg("image"), arg("connexity") ),
       doc__ptisolated__c__
     );

Advanced

This file contains C++ macro language and template metaprogramming, which is difficult to understand. The file is first treated with the preprocessor. The generated code looks like this:

  template < class image_type,
             int (*mcfunction) (
               typename convert_if<image_type>::type
               )
             >
  image_type make_function( const image_type& image )
  {
    image_type result;
    result = image.clone();
    if (!mcfunction(result )) { {
        std::stringstream fullmessage;
        fullmessage << "in ui_make_function.hpp: " << "mcfunction failed";
        call_error(fullmessage.str());
      };
    }
    return result;
  };
  
  template < class image_type,
             class T0 ,
             int (*mcfunction) (
               typename convert_if<image_type>::type ,
               typename convert_if<T0>::type )
             >
  image_type make_function( const image_type& image , T0 t0 )
  {
    image_type result;
    result = image.clone();
    if (!mcfunction(result , t0)) { {
        std::stringstream fullmessage;
        fullmessage << "in ui_make_function.hpp: " << "mcfunction failed";
        call_error(fullmessage.str());
      };
    }
    return result;
  };
  
  template < class image_type,
             class T0 ,
             class T1 ,
             int (*mcfunction) (
               typename convert_if<image_type>::type ,
               typename convert_if<T0>::type ,
               typename convert_if<T1>::type )
             >
  image_type make_function( const image_type& image , T0 t0 , T1 t1 )
  {
    image_type result;
    result = image.clone();
    if (!mcfunction(result , t0 , t1)) { {
        std::stringstream fullmessage;
        fullmessage << "in ui_make_function.hpp: " << "mcfunction failed";
        call_error(fullmessage.str());
      };
    }
    return result;
  };

The macro generates the make_function template for each number of parameters. The template takes the specified parameters and wraps the function in Python. The most important part of the macro is the conversion of the 'xvimage*' pointer into the appropriate image class (like 'char_image').