creating simple Python scripting interfaces via C++

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ben Sizer

    #1

    creating simple Python scripting interfaces via C++

    I have Python embedded in a C++ application (yes, yes, I know, I'd
    prefer it the other way around too) and essentially need to expose some
    read-only values and functions to Python so it can be used to script
    the host application.

    When scripting a similar app in TCL, it's possible to associate each
    command with some client data, so that the command can be written in
    the script as a free function but it actually executes in some sort of
    context, accessed via the client data pointer in C++. In Python, there
    doesn't appear to be this mechanism, so I think I'd have to inject the
    context in another way, either as some sort of module-level global, or
    as an object, implementing the previously free functions as methods.

    Is this correct? If so, what is the simplest way of implementing the
    former method - inserting the pointer to the required context as a long
    (via PyDict_SetItemS tring(globals, "context", PyInt_FromLong( pointer))
    or similar) and then converting it back in the bound function? And for
    the latter method, is it possible to make an arbitrary object and then
    attach methods and the context data? Or will I have to create a whole
    Python class for this (as in


    I'm not interested in wrapping whole C++ objects at this stage, and
    libraries like Boost::Python aren't currently an option. I just need a
    few pointers on doing it the low-level way for now.

    --
    Ben Sizer

  • Ben Sizer

    #2
    Re: creating simple Python scripting interfaces via C++

    Ok, my first attempt at this creates proxy objects in Python, and
    stores a pointer to the C++ instance in the Python object. I cast that
    pointer to an int and pass it as a single parameter to the object's
    __init__ function.

    static PyObject* Actor_init(PyOb ject *self, PyObject *args)
    {
    PyObject* selfParam;
    PyObject* ptrValue;
    if (!PyArg_ParseTu ple(args, "OO", &selfParam, &ptrValue))
    return NULL;

    PyObject_SetAtt rString(selfPar am, "_cpp_ptr", ptrValue);

    Py_INCREF(Py_No ne);
    return Py_None;
    }

    I have no idea why self is always NULL, when I'm calling the functions
    as methods of an object. Any ideas why this is the case? For what it's
    worth I attach each method via the PyMethodDef -PyCFunction_New ->
    PyMethod_New -PyDict_SetItemS tring(classDict ) route.

    To get data back from the C++ object to Python, I extract that value
    and cast it back to the appropriate pointer type.

    static PyObject* Actor_showName( PyObject *self, PyObject *args)
    {
    PyObject* selfParam;
    if (!PyArg_ParseTu ple(args, "O", &selfParam))
    return NULL;

    PyObject* cppPtr = PyObject_GetAtt rString(selfPar am, "_cpp_ptr") ;
    long cppPtrVal = PyInt_AsLong(cp pPtr);
    Actor* pActor = reinterpret_cas t<Actor*>(cppPt rVal);

    // Delegate to the C++ object
    pActor->ShowName();

    Py_INCREF(Py_No ne);
    return Py_None;
    }

    I've omitted some error checking, but this is the way I'm going for
    now. Are there any glaring errors I've made (apart from perhaps
    assuming sizeof(pointer) <= sizeof(long), that is)? And is there
    anywhere else more appropriate that I should be asking this question,
    given the lack of responses to this and my other embedding topic so
    far?

    --
    Ben Sizer

    Comment

    • David Boddie

      #3
      Re: creating simple Python scripting interfaces via C++

      Ben Sizer wrote: And is there anywhere else more appropriate that I
      should be asking this question, given the lack of responses to this
      and my other embedding topic so far? You could try asking on the C++
      SIG mailing list at python.org:
      http://mail.python.org/mailman/listinfo/c++-sig David

      Comment

      Working...