Vaillancourt
Vaillancourt

Reputation: 1418

Is there a way to generate a c++ class from a python class and bind it a compile time?

Is there a way to generate a relatively clean c++ class from a python class and bind it at compile-time?

For instance, if I have this python class:

class CarDef:
    acceleration = 1000.0
    brake = 1500.0
    inertia = acceleration * 0.1 * brake

    def __init__(self):
        pass

I'd like to have the corresponding c++ class:

class CarDef
{
public:
  double acceleration;
  double brake;
  double inertia;
  CarDef() 
  : acceleration( 1000.0 )
  , brake( 1500.0 )
  , inertia ( 150000.0 )
  {};
};

The resulting c++ class could be different, as well as the original python class: I could use a "getter methods" paradigm instead of class attributes.

What I'm trying to achieve is to create resource files in python that I'll be able to use in my c++ application. The goal is to reduce as much as possible the amount of code the end-user will have to write to add and use parameters; and it must avoid string comparison during the "running phase" (it's allowed during the "initialization phase").

I'd like the user to have to enter the resource name only twice: once in the python class, and once in the place where the resource will be used in the c++, assuming that the "magic" is going to bind the two items (either at run-time (which I doubt could be done without string comparison) or at compile time (an in-between step generates c++ class before the project is compiled)). This is why I'm going from python to c++; I believe that going from c++ to python would require at least 2 python files: one that is generated and one that inherits from the latter (to avoid overwriting already specified resources).

The end-user use would look like this:

// A singleton definition manager
class DefManager
{
  CarDef mCarDef;
public:
  static DefManager& GetReference() 
  {
    static DefManager instance;
    return instance;
  }

  CarDef& getCarDef() { return mCarDef; }
};

// One would use the generated CarDef class like this:
mCar.setSpeed( mCar.getSpeed() +  DefManager.GetReference().getCarDef().acceleration );

With this in mind, the python code is strictly outside of the c++ code.

One obvious problem I see is how to know what type a python attribute or method returns. I've seen a bit of examples of Cython, and it's seems to be able to use types (which is great!), but I haven't seen any examples where it could do what I need. Also, c generated code seems to still need Python.h and thus the cpython api libraries when compiling.

Is there any ways I could achieve this? Are there better way to do it?

Upvotes: 8

Views: 596

Answers (3)

buc030
buc030

Reputation: 434

There is a logical problem with doing what you ask.
Python is weakly typed.
In python one can even change the type of a certain data member during run time.
So say you have two objects of type

CarDef

Lets call them obj1 and obj2. Lets say you have a setter:

setIntX(self): 
    self.x = 5

and lets say you also have a setter:

setStringX(self): 
    self.x = "5"

Then what type will member x have in your C++ class?
This can only be decided during run time, and more than one C++ class might be necessary to model one python class.
However a template class from python might be possible, and quite interesting actually.
Also maybe a general solution is not possible, but if you assume no member have ambiguous type it is possible.

Upvotes: 0

Nicholas Smith
Nicholas Smith

Reputation: 68

You could embed python in your C++ code or vice versa. There are tons of helper functions, though a little ugly, can be very powerful and might be able to accomplish what you want, though I'm not sure I'm entirely understanding your question. This doesn't require the cython api, but does still require Python.h.

Upvotes: 0

wheaties
wheaties

Reputation: 35980

There is a way to go from C++ to Python but I do not know of any way of going from Python to C++. If you don't mind writing your code in C++ first, you can use the tool SWIG to auto generated for you Python classes.

Do note there are a few limitations around exception handling. You can set up to have your Python code throw C++ exceptions but the type of exception can be lost in translation. You also need to pay attention to handling of reference counted objects. SWIG will generate reference counting for Python which can sometimes delete objects unexpectedly.

If you don't like using a tool such as SWIG, there is also Boost.Python for C++. Again, this is C++ for Python bindings and does not auto generate C++ from Python.

Upvotes: 1

Related Questions