I've got a struct that looks like this:
foo.h:
struct A {
string a;
string b;
};
It has the matching definition in a .pyx file, as well as a python wrapper:
lib_foo.pyx:
cdef extern from "foo.h":
cdef struct A:
string a
string b
cdef class PyA:
cdef A* thisptr
def __cinit__(self):
self.thisptr = <A*>malloc(sizeof(A))
cdef A* getThis(self):
return self.thisptr
def bar(self):
self.thisptr.a = "Hello" # works fine!
def bar2(self):
return self.thisptr.a # this too!
def bar(PyA f):
f.getThis().a = "Hello"
def bar2(PyA a):
return f.getThis().a
This builds fine without any problems, I get a libfoo.so out of it, which I use in a simple test script:
import libfoo
f = libfoo.PyA()
#f.bar() no problems
libfoo.bar(f) # this line and the next have unpredictable behavior!
print libfoo.bar2(f)
Over repeated runs, sometimes this will successfully print "Hello", and other times a segfault. Even stranger, the two functions bar and bar2 seem to work just fine as member functions of class PyA. I have done a bunch of cython wrapping, using just such a getThis() function in order to supply pointers to classes and structs, never had a problem until now. Could it be the strings causing the issue?
edit: setup.py
from distutils.core import setup
import distutils.util as du
from distutils.extension import Extension
from Cython.Distutils import build_ext
import os
os.environ["CC"] = "/app/gcc/4.8.2/bin/g++"
os.environ["CXX"] = "/app/gcc/4.8.2/bin/g++"
os.environ["CPP"] = "/app/gcc/4.8.2/bin/g++"
os.environ["CMAKE_CXX_COMPILER"] = "/app/gcc/4.8.2/bin/g++"
ext_modules = [
Extension(
name = "libfoo",
sources = ["lib_foo.pyx"],
include_dirs = ["/usr/local/include", "/usr/include"],
library_dirs = ["/usr/local/lib", "/usr/lib"],
language = "c++",
)]
setup(
name = "libfoo",
cmdclass = {"build_ext" : build_ext},
ext_modules = ext_modules
)