views:

126

answers:

1

Hi all,

I have written some physics simulation code in C++ and parsing the input text files is a bottleneck of it. As one of the input parameters, the user has to specify a math function which will be evaluated many times at run-time. The C++ code has some pre-defined function classes for this (they are actually quite complex on the math side) and some limited parsing capability but I am not satisfied with this construction at all.

What I need is that both the algorithm and the function evaluation remain speedy, so it is advantageous to keep them both as compiled code (and preferrably, the math functions as C++ function objects). However I thought of glueing the whole simulation together with Python: the user could specify the input parameters in a Python script, while also implementing storage, visualization of the results (matplotlib) and GUI, too, in Python.

I know that most of the time, exposing C++ classes can be done, e.g. with SWIG but I still have a question concerning the parsing of the user defined math function in Python:

Is it possible to somehow to construct a C++ function object in Python and pass it to the C++ algorithm? E.g. when I call

f = WrappedCPPGaussianFunctionClass(sigma=0.5)
WrappedCPPAlgorithm(f)

in Python, it would return a pointer to a C++ object which would then be passed to a C++ routine requiring such a pointer, or something similar... (don't ask me about memory management in this case, though :S)

The point is that no callback should be made to Python code in the algorithm. Later I would like to extend this example to also do some simple expression parsing on the Python side, such as sum or product of functions, and return some compound, parse-tree like C++ object but let's stay at the basics for now.

Sorry for the long post and thx for the suggestions in advance.

+3  A: 

I do things similar to this all the time. The simplest solution, and the one I usually pick because, if nothing else, I'm lazy, is to flatten your API to a C-like API and then just pass pointers to and from Python (or your other language of choice).

First create your classes

class MyFunctionClass
{
  public:
    MyFunctionClass(int Param)
    ...
};

class MyAlgorithmClass
{
  public:
    MyAlgorithmClass(myfunctionclass& Func)
    ...
};

Then create a C-style api of functions that creates and destroys those classes. I usually flatted in out to pass void* around becuase the languages I use don't keep type safety anyway. It's just easier that way. Just make sure to cast back to the right type before you actually use the void*

    void* CreateFunction(int Param)
    {
      return new MyFunctionClass(Param);
    }

    void DeleteFunction(void* pFunc)
    {
        if (pFunc)
            delete (MyFunctionClass*)pFunc;
    }

    void* CreateAlgorithm(void* pFunc)
    {
      return new MyAlgorithmClass(*(MyFunctionClass*)pFunc)
    }

    void DelteAlgorithm(void* pAlg)
    {
       if (pAlg)
           delete (MyAlgorithmClass*)pAlg;
    }

No all you need to do is make python call those C-style function. In fact, they can (and probably should) be extern "c" functions to make the linking that much easier.

miked