how to use Cython to use Python from C++

Hi All,

Im running into some bottlenecks with some python code and I started to look into cython to wrap my class. My problem is that my now rewritten c++ class requires a class or two that I have written in python. Im not sure if its possible but is it possible to cythonize a python file and #include it into my c++ code?

In a little test I am writing I have managed to get everything to compile but I cant link a cythonized class to c++ (“ld returned 1 exit status”). I get “undefined reference” errors when im compiling. If I implement the class in the header file everything works out.

any error like unresolved externals/symbols maybe?

nope, ill post the example code im working on along with the the output from me running the setup file sometime this week.

ok so I some test code to try to figure this out. What I have is example_c.cpp and example.h which would represent the class that I need to rewrite in c++. I then have requiredClass.pyx which is plain python which I would cythonize (it generates a c++ file) and a requiredClass.h which I included into example_c.cpp and example.h. Using the distutils build it spits out that the methods from requiredClass are undefined, even though I am compiling with the cython generated cpp file. At this point I dont know if the files are just not linking properly (because im doing something wrong) or if what I am trying to do cant be done. Any help would be greatly appreciated.

example.h

#ifndef __EXAMPLE_H_INCLUDED__
#define __EXAMPLE_H_INCLUDED__

#include "requiredClass.h"

class Example{
	public:
		int x, y;
		RequiredClass *r;
		Example(int xx, int yy, RequiredClass *rr);
		int getX(){return x;}
		int getY(){return y;}
		int doSomething(int z);

};
#endif

example_c.cpp

#include "example.h"
#include "requiredClass.h"
Example::Example(int xx, int yy,RequiredClass *rr){
	x=xx;
	y=yy;
	r=rr;
}

int Example::doSomething(int z){
	return x*y*z*(r->getQ());
}

requiredClass.h

#ifndef __REQUIREDCLASS_H_INCLUDED__
#define __REQUIREDCLASS_H_INCLUDED__

class RequiredClass{
	public:
		RequiredClass(int qq);//{q=qq;}
		int getQ();//{return q;}
		int q;
};

#endif

requiredClass.pyx

class RequiredClass():
    def __init__(self, q):
        self.q=q
    def getQ(self):
        return self.q

example.pyx

cdef extern from "requiredClass.h":
    cppclass RequiredClass:
        RequiredClass(int q) except +
        int q
        int getQ()
        
cdef class PyRequiredClass:
    cdef RequiredClass *thisptr
    def __cinit__(self, int q):
        self.thisptr=new RequiredClass(q)
    def __dealloc__(self):
        del self.thisptr
    def getQ(self):
        return self.thisptr.getQ()


cdef extern from "example.h":
    cdef cppclass Example:
        Example(int xx, int yy, RequiredClass *rr) except +
        int x, y
        RequiredClass r
        int getX()
        int getY()
        int doSomething(int z)
        
cdef class PyExample:
    cdef Example *thisptr
    def __cinit__(self, int xx, int yy, PyRequiredClass rr):
        self.thisptr=new Example(xx,yy,rr.thisptr)
    def __dealloc__(self):
        del self.thisptr
    def getX(self):
        return self.thisptr.getX()
    def getY(self):
        return self.thisptr.getY()
    def doSomething(self, int z):
        return self.thisptr.doSomething(z)

setup.py

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension("requiredClass", ["requiredClass.pyx"],language="c++")]

setup(
  name = 'requiredClass module',
  cmdclass = {'build_ext': build_ext},
  ext_modules = ext_modules
)

ext_modules = [Extension("example", ["example_c.cpp","requiredClass.cpp","example.pyx"],language="c++")]
setup(
  name = 'example module',
  cmdclass = {'build_ext': build_ext},
  ext_modules = ext_modules
)

OK, so I am not sure that what I want to do is possible so I have thought of a way to implement my AI so that I will not need to include other classes I have written. My AI will be written in c++ and require some includes from Panda. I know a bit of c++ but I have never manually linked anything before and I have never encountered having to use a specific compiler also.

so I have a few questions:

  1. Do I need to use MSVS to compile my AI code or can I use mingw (or even cython when I bind my AI to python)?
  2. How do I know which libraries to link? Do I need all of them if Im using only a couple of classes (i.e NodePath)?
  3. If I have an instance of showbase from python, do I still need to init panda on the c++ side?
  4. If I need things like the messenger or taskMgr will I be able to simply pass those into my c++ class by calling .this (would self.taskMgr.this be usable to pass the c++ reference, got this from the cython blog post)?

Thanks in advanced