On Sat, Aug 16, 2014 at 9:07 PM, Marcus Brinkmann <marcus.brinkm...@ruhr-uni-bochum.de> wrote: > Hi, > > ok, this is not as easy as I originally thought. I fixed a couple of things > that prevented the suggested syntax from working, but the linking stage has > additional challenges, as there is currently no support for cimporting a > native cppclass from one module to another (akin to the "api" feature or the > "public" symbol import function feature). It's also not sure how this > should work exactly, so I am giving up. > > I settled on a work around using "cdef public" C functions and making use of > cimport and the automatic symbol import feature. This does not give access > to the full type, but it's sufficient for my use case. > > The following two changes were somewhat useful in my explorations: > > 1. Fix the "this" pointer misreference. This is an actual bug, so I made a > pull request: > > https://github.com/cython/cython/pull/316 > > 2. The missing constructor declaration generated when cimporting the pxd > file is easy to fix by not testing for "defining or name != "<init>") in > CppClassScope. However, this breaks a test case, because > NewExprNode.inferType adds the implicit default constructor under the name > "<init>" without a proper cname. So I made a larger change that fixes this, > too: > > https://github.com/lambdafu/cython/tree/lambdafu/cpp_declare_constructor > > I didn't make a pull request, because currently cimport'ing an external > cppclass declaration is not useful without some way to add the runtime > dependency as well... > > Thanks and sorry for the noise. It wasn't entirely clear to me what the > state of cppclass support in Cython is until I read the source code.
Thanks. As you observed, defining C++ classes in Cython is still somewhat of a beta feature. > On 08/12/2014 04:57 AM, Marcus Brinkmann wrote: >> >> Hi, >> >> I want to declare and define C++ classes from Cython. Sure, I could >> write them in native C++, but it's just small glue code, and I prefer to >> let Cython handle the GIL and all the other good stuff. >> >> First, for reference, the following works (c.f. >> tests/run/cpp_classes_def.pyx): >> >> == cython --cplus example1.pyx ============ >> cdef cppclass Foo "Foo": >> int _foo >> __init__(int foo) nogil: >> this._foo = foo >> __dealloc__() nogil: >> pass >> =========================================== >> >> This will emit a declaration for Foo and the implementations of the >> constructor and destructor (output is truncated to show relevant parts >> only): >> >> struct Foo { >> int _foo; >> Foo(int); >> virtual ~Foo(void); >> }; >> Foo::Foo(int __pyx_v_foo) { >> this->_foo = __pyx_v_foo; >> } >> Foo::~Foo(void) { >> } >> >> Now, I want to export the class to other cython files. The following >> does not work, and I think it's a bug: >> >> == example2.pxd =========================== >> cdef extern cppclass Foo: >> int _foo >> __init__(int foo) >> __dealloc__() >> =========================================== >> >> == cython --cplus example2.pyx ============ >> cdef cppclass Foo: >> __init__(int foo) nogil: >> this._foo = foo >> __dealloc__() nogil: >> pass >> =========================================== >> >> == cython --cplus example3.pyx ============ >> from example2 cimport Foo >> >> cdef Foo* foo_p = new Foo(2) >> =========================================== >> >> This fails for example2 with an obscure error message: >> >> $ cython --cplus example2.pyx >> example2.pyx:3:8: undeclared name not builtin: this >> ...more spurious errors... >> >> For example3, Cython runs through but trying to compile shows the actual >> problem (which you can also see in example2 if you shift things around a >> bit): >> >> $ g++ -fPIC -shared -o example3.so -I /usr/include/python2.7 example3.cpp >> example3.cpp: In function ‘void initexample3()’: >> example3.cpp:775:38: error: no matching function for call to >> ‘Foo::Foo(int)’ >> __pyx_v_8example3_foo_p = new Foo(2); >> >> This is in the generated code: >> >> /*--- Type declarations ---*/ >> struct Foo; >> struct Foo { >> int _foo; >> virtual ~Foo(void); >> }; >> >> It's missing the constructor declaration! >> >> I traced this a bit down the Compiler/Symtab.py and found this part in >> CppClassScope::declare_var: >> >> 4e07fc52 (Robert Bradshaw 2012-08-21 00:46:00 -0700 2112) if name >> != "this" and (defining or name != "<init>"): >> 4e07fc52 (Robert Bradshaw 2012-08-21 00:46:00 -0700 2113) >> self.var_entries.append(entry) >> >> Here defining is 0, so the declaration is skipped. I don't know Cython >> internals, so I am hoping someone who does can fix this easily given the >> above information or point me in the right direction. >> >> Thanks a lot for Cython, it's very useful! >> >> Marcus Brinkmann >> _______________________________________________ >> cython-devel mailing list >> cython-devel@python.org >> https://mail.python.org/mailman/listinfo/cython-devel > > > _______________________________________________ > cython-devel mailing list > cython-devel@python.org > https://mail.python.org/mailman/listinfo/cython-devel _______________________________________________ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel