[pygccxml-development] Feature proposal: "Argument policies"
Brought to you by:
mbaas,
roman_yakovenko
|
From: Matthias B. <ba...@ir...> - 2006-04-18 17:06:36
|
Hi,
here's a suggestion for a new feature that should deal with the problem
that C++ functions that have more than just one output (by taking
references) cannot be translated literally to Python. Even worse, they
compile without errors but they are plain useless in Python because
there's no way to invoke such functions.
One example of such a function is the already mentioned getSize(int&
width, int& height) method that returns the resolution of an image.
It is my understanding that such a function requires a wrapper function
that changes the signature so that the function takes no arguments and
returns a Python tuple with the result.
Having to write those wrappers manually is quite a repetitive and
tedious task. So my suggestion is to introduce something similar to call
policies, that's why I called it "argument policies". The idea is just
that for each "problematic" argument you specify that it needs special
treatment. In the above case, pyplusplus needs to know that the
arguments are actually used for output values instead of input values.
This could be specified like this:
Image.Method("getSize").setArgPolicy(Output(1), Output(2))
setArgPolicy() is a new decorator that takes an arbitrary number of
"argument policies" as input. The "Output" policy takes one integer as
argument which is the index of the argument it applies to. So by writing
"Output(1)", the user specifies that the first argument is actually an
output value. This is already enough information so that a wrapper
function can be created automatically. The wrapper function would take
no arguments anymore and return two integers with the result.
Another example is a function that takes a pointer to a double as input.
For example:
void getTranslation(double t[3])
void setTranslation(double t[3])
In the first case, 't' is an ouput argument used to store the result
whereas in the second case 't' is an input argument. The above Output
policy cannot be used because Python has no double[3] type. Instead, the
wrapper needs some additional code to copy a Python sequence into a
double array or vice versa:
cls.Method("getTranslation").setArgPolicy(OutputArray(1,3))
cls.Method("setTranslation").setArgPolicy(InputArray(1,3))
The first argument to the OutputArray/InputArray class is again the
index of the argument this policy applies to. The second argument is the
size of the array. These policies will then also take care of converting
between Python sequences and C arrays.
More policies can be defined as appropriate. For example, variants of
the InputArray/OutputArray policies could take the array size from an
additional argument.
The nice thing about this framework is that another thing I wanted to
have fits nicely into it. For the Maya SDK, I wanted to convert Status
objects into exceptions. This can also be expressed with those policies
by using a custom policy such as "MStatusToException" that adds code
that throws an exception when an error has occurred. There can also be
policies that do something with the return value, etc.
I have already implemented a prototype version of this in the
experimental module. So far, it has worked quite fine for my Maya
bindings (by the way, I have just released a first "preview" version of
those bindings, so if anybody wants to have a look how I create them,
have a look at the 'maya' package over here: http://cgkit.sourceforge.net/)
Currently, my implementation would not work when a class already
receives wrappers generated by pyplusplus. But I think this could be
changed so that the wrappers created by pyplusplus use the same
framework for specifying wrapper source code (but this needs
modification inside pyplusplus).
The above argument policies use the same "code creator" concept that
pyplusplus already uses, the interface of those code creators is just
different because there are actually two places where code can be
placed, either before or after the original function invocation. And in
addition to creating code, those special code creators can also modify
the signature of a function. So pyplusplus would have to use those
special code creators instead of just creating one static block of C++
source code for the entire wrapper function.
Any comments? Do you already see cases where this could not work or how
it could be improved?
- Matthias -
|