[C++-sig] Re: Exposing C++ objects to Python at runtime
Raoul Gough
RaoulGough at yahoo.co.uk
Wed Nov 26 19:50:30 CET 2003
Daniel Wallin <dalwan01 at student.umu.se> writes:
> Raoul Gough wrote:
>> David Abrahams <dave at boost-consulting.com> writes:
>>
>>>Raoul Gough <RaoulGough at yahoo.co.uk> writes:
>>>
[snip]
>> The only difficulty I've thought of would be handling return values.
>> For instance, somewhere you have to have a conversion from the C++
>> return type to a PyObject * (for the Python engine) or the
>> corresponding type for different engines. Maybe a double-dispatch
>> would handle this, meaning a certain amount of scripting language
>> dependant code in the function descriptor base class?
>
> I thought it would just work like:
>
> PyObject* python_function_wrapper()
> {
> function& fn = /* something */;
>
> const type_info* args = fn.arg_types();
>
> void** storage_table = /* something */;
>
> for (int i = 0; i < fn.arity(); ++i)
> {
> void* storage = allocate_storage_for_converter(args[i]);
> perform_conversion(args[i], i, storage, py_args);
So perform_conversion knows (a) what the scripting engine argument
type is and (b) what the required C++ argument type is. For example,
you have a C++ function:
void do_something (some_udt);
and we need code somewhere to create a some_udt object from a PyObject
*, from a lua_State * or whatever. I guess that means the function
descriptor can't be truly universal, since it is supposed to be the
only place that has compile-time knowledge of the C++ types
involved. e.g.
function<...>::convert_argument0 (PyObject *src, void *dst) {
// create an arg_vector<0> type from PyObject at dst
}
function<...>::convert_argument0 (lua_State *src, void *dst) {
// create an arg_vector<0> object from lua_State at dst
}
etc.
> storage_table[i] = storage;
> }
>
> void* result_storage = allocate_storage_for_converter(
> fn.result_type()
> );
>
> fn.invoke(storage_table, result_storage);
>
> return perform_result_conversion(
> fn.result_type()
> , result_storage
> );
If I'm right about the parameter conversions, then the same would
apply here for the return value conversion.
> }
>
> and function::invoke, simplified, would just do..
>
> void function::invoke(void* const* args_storage, void* result_storage)
> {
> new (result_storage) ResultType(
> m_fn(
> static_cast<A0*>(args_storage[0])
> , static_cast<A1*>(args_storage[1])
> , etc..
> )
> );
> }
>
> I guess you'd also need a virtual tail call that can destroy the
> result..
>
> Of course, the converter lookup would be done at init time and stored.
But where does the C++ code for the converter (with compile-time
knowledge of the C++ types) come from?
--
Raoul Gough.
export LESS='-X'
More information about the Cplusplus-sig
mailing list