⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pyste.txt

📁 C++的一个好库。。。现在很流行
💻 TXT
📖 第 1 页 / 共 2 页
字号:
guess the semantics of functions that return pointers or references. In this
case, the user must manually specify the policy. Policies are explained in the
[@../../doc/tutorial/doc/call_policies.html tutorial].

The policies in Pyste are named exactly as in Boost.Python, only the syntax is
slightly different. For instance, this policy:

    return_internal_reference<1, with_custodian_and_ward<1, 2> >()

becomes in Pyste:    

    return_internal_reference(1, with_custodian_and_ward(1, 2))

The user can specify policies for functions and virtual member functions with
the [^set_policy] function:

    set_policy(f, return_internal_reference())
    set_policy(C.foo, return_value_policy(manage_new_object))

[blurb 
[$theme/note.gif] [*What if a function or member function needs a policy and
the user doesn't set one?][br][br] If a function needs a policy and one
was not set, Pyste will issue a error.  The user should then go in the
interface file and set the policy for it, otherwise the generated cpp won't
compile.
]

[blurb
[$theme/note.gif] 
Note that for functions that return [^const T&], the policy
[^return_value_policy<copy_const_reference>()] wil be used by default, because
that's normally what you want. You can change it to something else if you need
to, though.
]

[page:1 Templates]

Template classes can easily be exported too, but you can't export the template
itself... you have to export instantiations of it! So, if you want to export a
[^std::vector], you will have to export vectors of int, doubles, etc.

Suppose we have this code:

    template <class T>
    struct Point
    {
        T x;
        T y;
    };

And we want to export [^Point]s of int and double:

    Point = Template("Point", "point.h")
    Point("int")
    Point("double")

Pyste will assign default names for each instantiation. In this example, those
would be "[^Point_int]" and "[^Point_double]", but most of the time users will want to
rename the instantiations:

    Point("int", "IPoint")         // renames the instantiation
    double_inst = Point("double")  // another way to do the same
    rename(double_inst, "DPoint")

Note that you can rename, exclude, set policies, etc, in the [^Template] object
like you would do with a [^Function] or a [^Class]. This changes affect all
[*future] instantiations:

    Point = Template("Point", "point.h")
    Point("float", "FPoint")        // will have x and y as data members
    rename(Point.x, "X")
    rename(Point.y, "Y")
    Point("int", "IPoint")          // will have X and Y as data members
    Point("double", "DPoint")       // also will have X and Y as data member

If you want to change a option of a particular instantiation, you can do so:

    Point = Template("Point", "point.h")
    Point("int", "IPoint")          
    d_inst = Point("double", "DPoint")       
    rename(d_inst.x, "X")           // only DPoint is affect by this renames,
    rename(d_inst.y, "Y")           // IPoint stays intact

[blurb [$theme/note.gif] [*What if my template accepts more than one type?]
[br][br]
When you want to instantiate a template with more than one type, you can pass
either a string with the types separated by whitespace, or a list of strings
'''("int double" or ["int", "double"]''' would both work).
]

[page:1 Wrappers]

Suppose you have this function:

    std::vector<std::string> names();

But you don't want to [@../../doc/v2/faq.html#question2 to export std::vector<std::string>], 
you want this function to return a python list of strings. Boost.Python has
excellent support for things like that:

    list names_wrapper()
    {
        list result;
        // call original function
        vector<string> v = names();
        // put all the strings inside the python list
        vector<string>::iterator it;
        for (it = v.begin(); it != v.end(); ++it){
            result.append(*it);    
        }
        return result;
    }
    
    BOOST_PYTHON_MODULE(test)
    {
        def("names", &names_wrapper);
    }

Nice heh? Pyste supports this mechanism too. You declare the [^names_wrapper]
function in a header named "[^test_wrappers.h]" and in the interface file:

    Include("test_wrappers.h")
    names = Function("names", "test.h")
    set_wrapper(names, "names_wrapper")

You can optionally declare the function in the interface file itself:

    names_wrapper = Wrapper("names_wrapper",
    """
    list names_wrapper()
    {
        // code to call name() and convert the vector to a list...
    }
    """)
    names = Function("names", "test.h")
    set_wrapper(names, names_wrapper)

The same mechanism can be used with member functions too. Just remember that
the first parameter of wrappers for member functions is a pointer to the
class, as in:

    struct C
    {
        std::vector<std::string> names();
    }

    list names_wrapper(C* c)
    {
        // same as before, calling c->names() and converting result to a list 
    }

And then in the interface file:

    C = Class("C", "test.h")
    set_wrapper(C.names, "names_wrapper")

[blurb 
[$theme/note.gif]Even though Boost.Python accepts either a pointer or a
reference to the class in wrappers for member functions as the first parameter,
Pyste expects them to be a [*pointer]. Doing otherwise will prevent your
code to compile when you set a wrapper for a virtual member function.
]

[page:1 Exporting An Entire Header]

Pyste also supports a mechanism to export all declarations found in a header
file. Suppose again our file, [^hello.h]:

    struct World
    {
        World(std::string msg): msg(msg) {} 
        void set(std::string msg) { this->msg = msg; }
        std::string greet() { return msg; }
        std::string msg;
    };

    enum choice { red, blue };
    
    void show(choice c) { std::cout << "value: " << (int)c << std::endl; } 

You can just use the [^AllFromHeader] construct:

    hello = AllFromHeader("hello.h")

this will export all the declarations found in [^hello.h], which is equivalent
to write:

    Class("World", "hello.h")
    Enum("choice", "hello.h")
    Function("show", "hello.h")

Note that you can still use the functions [^rename], [^set_policy], [^exclude], etc. Just access
the members of the header object like this:

    rename(hello.World.greet, "Greet")
    exclude(hello.World.set, "Set")

[blurb    
[$theme/note.gif] [*AllFromHeader is broken] in some cases. Until it is fixed,
use at you own risk.
]


[page:1 Smart Pointers]

Pyste for now has manual support for smart pointers. Suppose:

    struct C
    {
        int value;
    };

    boost::shared_ptr<C> newC(int value)
    {
        boost::shared_ptr<C> c( new C() );
        c->value = value;
        return c;
    }

    void printC(boost::shared_ptr<C> c)
    {
        std::cout << c->value << std::endl;
    }

To make [^newC] and [^printC] work correctly, you have to tell Pyste that a
convertor for [^boost::shared_ptr<C>] is needed.

    C = Class('C', 'C.h')
    use_shared_ptr(C)
    Function('newC', 'C.h')
    Function('printC', 'C.h')

For [^std::auto_ptr]'s, use the function [^use_auto_ptr].

This system is temporary, and in the future the converters will automatically be
exported if needed, without the need to tell Pyste about them explicitly.

[h2 Holders]

If only the converter for the smart pointers is not enough and you need to
specify the smart pointer as the holder for a class, use the functions
[^hold_with_shared_ptr] and [^hold_with_auto_ptr]:

    C = Class('C', 'C.h')
    hold_with_shared_ptr(C)
    Function('newC', 'C.h')
    Function('printC', 'C.h') 

[page:1 Global Variables]

To export global variables, use the [^Var] construct:

    Var("myglobal", "foo.h")

Beware of non-const global variables: changes in Python won't reflect in C++!
If you really must change them in Python, you will have to write some accessor
functions, and export those.


[page:1 Adding New Methods]

Suppose that you want to add a function to a class, turning it into a member
function:

    struct World
    {
        void set(std::string msg) { this->msg = msg; }
        std::string msg;
    };

    std::string greet(World& w)
    {
        return w.msg;
    }

Here, we want to make [^greet] work as a member function of the class [^World]. We do
that using the [^add_method] construct:

    W = Class("World", "hello.h")
    add_method(W, "greet")

Notice also that then you can rename it, set its policy, just like a regular
member function:

    rename(W.greet, 'Greet')

Now from Python:

    >>> import hello
    >>> w = hello.World()
    >>> w.set('Ni')
    >>> w.greet()
    'Ni'
    >>> print 'Oh no! The knights who say Ni!'
    Oh no! The knights who say Ni!


[page:1 Inserting Code]

You can insert arbitrary code in the generated cpps, just use the functions
[^declaration_code] and [^module_code]. This will insert the given string in the
respective sections. Example:

    # file A.pyste
    Class("A", "A.h")
    declaration_code("/* declaration_code() comes here */\n")
    module_code("/* module_code() comes here */\n")

Will generate:

    // Includes ====================================================================
    #include <boost/python.hpp>

    // Using =======================================================================
    using namespace boost::python;

    // Declarations ================================================================

    /* declaration_code() comes here */

    // Module ======================================================================
    BOOST_PYTHON_MODULE(A)
    {
        class_< A >("A", init<  >())
            .def(init< const A& >())
        ;

    /* module_code() comes here */
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -