[C++-sig] Re: Exposing C++ objects to Python at runtime

Raoul Gough RaoulGough at yahoo.co.uk
Tue Nov 25 01:28:48 CET 2003

Jonathan Warrington <jon at shirwin.com> writes:

> Ah, ok I think I see where the communication problem was now.
> What I was wanting to do, was have it so that my other components
> would only know of that scripting engine interface, and use that to
> register themselves at runtime when they are created, and therefore if
> my XYZ class changes all I have to do is recompile that.  Not have to
> generate new Boost.Python registration code, and recompile that
> wrapper.
> So,
> App Starts
> App creates an instance of Scripting Engine
> App creates an instance of class XYZ
> App passes scripting engine to XYZ->Init()
> XYZ registers what it wants to be scriptable as scriptable

Well, I don't know how realistic this is. IIUC, you want some kind of
an abstract interface that allows you to add new functions, object
types and methods to various scripting engines. In this way, your
classes can expose themselves to any of the engines, while having
compile-time dependencies only on the abstract interface.

So consider the following:

>>> //Script function takes an arg count, an arg array, and returns a
>>> //value
>>> typedef void (*SCRIPT_FUNCTION)( int, ScriptVal**, ScriptVal* );
>>> struct SW_ScriptEngine{
>>>	virtual void initialize() = 0;
>>>	virtual void release() = 0;
>>>	virtual ScriptVal* executeScript(String script) = 0;
>>>	virtual bool registerFunction(String name, SCRIPT_FUNCTION
>>> func, String moduleName) = 0;

class my_class {
  void function1(int);
  int function2() const;

  void register_self (SW_ScriptEngine *eng_ptr) {
    eng_ptr->registerFunction (&function1);
    eng_ptr->registerFunction (&function2);

Now the type of function1 is "void (my_class::*)(int)" and the type of
function2 is "int (my_class::*)() const". How is registerFunction
going to be able to deal with those member functions (and all possible
others)? That's before you look at registering constructors, virtual
functions and so on - in fact, all of the issues that Boost.Python
already deals with in its own way.

> So, if I want to use javascript instead, I tell App to create a
> javascript engine instead, and then nothing else would need to change
> except the scripts being called.  No need to create new wrapper code.
> Does that make more sense as to what I'm wanting to be able to do?
> I'm assuming that it'd require certain restrictions on what can be
> registered, like the way I was doing the functions, where you can only
> register a specific function prototype, as long as it's not too
> restrictive, that's fine.

Separation of model, view and controller is all I can suggest (as
others have already implicity done). Your XYZ classes are your model
of the world, you create a script-enabled "view" on them in separate
code, and control it from the scripts. Naturally, the view must be
updated to reflect changes in the model.

Raoul Gough.
export LESS='-X'

More information about the Cplusplus-sig mailing list