Correct way to wrap a C++ class in Cython

148 views
Skip to first unread message

Jernej Azarija

unread,
Dec 20, 2014, 7:41:43 AM12/20/14
to sage-...@googlegroups.com
Dear sage-devel,

I have a question about the usage of Cython . I would like to wrap a C++  library whose definition looks like


=================================================
    namespace bliss {
      class AbstractGraph;
    }
     
    class AbstractGraph
    {
      friend class Partition;
    .............
    public:
      AbstractGraph();
      virtual ~AbstractGraph();
     
     
    class Graph : public AbstractGraph
    {
    public:
     
      Graph(const unsigned int N = 0);
      ~Graph();
     

    }
=================================================

Now as far as I understand Cython I *think* the following snippet should allow one to construct a Graph object


=================================================
cdef extern from "path to graph.hh"  namespace "bliss":

    cdef cppclass AbstractGraph:
        pass

    cdef cppclass Graph(AbstractGraph):
        Graph(const unsigned int)


def foo():
    cdef Graph *g = new Graph(10)
=================================================

Unfortunately I get a myriad of compile errors :


=================================================
build/cythonized/sage/graphs/bliss.cpp: In function 'PyObject* __pyx_pf_4sage_6graphs_5bliss_foo(PyObject*)':
build/cythonized/sage/graphs/bliss.cpp:254:28: error: expected primary-expression before '__attribute__'
 #     define CYTHON_UNUSED __attribute__ ((__unused__))
                            ^
build/cythonized/sage/graphs/bliss.cpp:578:3: note: in expansion of macro 'CYTHON_UNUSED'
   CYTHON_UNUSED Graph *__pyx_v_g; 
   ^
build/cythonized/sage/graphs/bliss.cpp:581:3: error: 'Graph' was not declared in this scope
   Graph *__pyx_t_1;
   ^

=================================================

The full compilation log is attached.

Can someone help me figure out my mistake in the above snippet? What would be the correct way of defining the Graph class as to be able to allocate it and later on use its methods?

Best,

Jernej






c.log

Volker Braun

unread,
Dec 20, 2014, 11:21:17 AM12/20/14
to sage-...@googlegroups.com
According to the compile log Graph is in namespace bliss, but according to what you posted it is not. Just post complete files if you have a question.

Volker Braun

unread,
Dec 20, 2014, 11:27:03 AM12/20/14
to sage-...@googlegroups.com
Also, which gcc version do you have? Did you compile Sage from source?

Jernej Azarija

unread,
Dec 21, 2014, 10:24:38 AM12/21/14
to sage-...@googlegroups.com
Volker,

I am using  gcc version 4.8.2 and the git version of sage that I myself compiled. I am also attaching the graph.hh file in case I trimmed it too much. Could you please check what is going on?

Thanks for your help,

Jernej
graph.hh

Volker Braun

unread,
Dec 22, 2014, 4:37:52 PM12/22/14
to sage-...@googlegroups.com
I don't see anything wrong, its somewhere in the stuff that you haven't posted. Inspect the generated cpp file or post a branch.

Jernej Azarija

unread,
Dec 23, 2014, 7:18:55 AM12/23/14
to Sage devel
Volker,

the branch should be accessible here http://git.sagemath.org/sage.git/log/?h=u/azi/CythonWrap

Best,

Jernej

--
You received this message because you are subscribed to a topic in the Google Groups "sage-devel" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sage-devel/NiWMTGsU54M/unsubscribe.
To unsubscribe from this group and all its topics, send an email to sage-devel+...@googlegroups.com.
To post to this group, send email to sage-...@googlegroups.com.
Visit this group at http://groups.google.com/group/sage-devel.
For more options, visit https://groups.google.com/d/optout.

Volker Braun

unread,
Dec 23, 2014, 1:12:56 PM12/23/14
to sage-...@googlegroups.com
Compiles fine for me (after changing the path to my graph.hh):

gcc -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/home/vbraun/Sage/git-temp/local/include -I/home/vbraun/Sage/git-temp/local/include/csage -I/home/vbraun/Sage/git-temp/src -I/home/vbraun/Sage/git-temp/src/sage/ext -I/home/vbraun/Sage/git-temp/local/include/python2.7 -c build/cythonized/sage/graphs/bliss.cpp -o build/temp.linux-x86_64-2.7/build/cythonized/sage/graphs/bliss.o -fno-strict-aliasing -w -fno-tree-dominator-opts

I can't import the resulting module because it doesn't link against bliss:

sage: import sage.graphs.bliss
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-1-75682df38474> in <module>()
----> 1 import sage.graphs.bliss

ImportError: /home/vbraun/Sage/git-temp/local/lib/python2.7/site-packages/sage/graphs/bliss.so: undefined symbol: _ZN5bliss5GraphC1Ej

But compilation is fine. You either aren't using the "gcc" that you think you are using, or maybe have a clashing header somewhere.

Jernej Azarija

unread,
Dec 24, 2014, 10:25:34 AM12/24/14
to Sage devel
Volker,

thank you for your help. I ended up updating & re-compiling Sage and it now works. As for the linkage issue, do you happen to know how to properly link against bliss in this case?

Best,

Jernej

Volker Braun

unread,
Dec 24, 2014, 7:13:27 PM12/24/14
to sage-...@googlegroups.com
In module_list.py you need

        Extension("sage.graphs.bliss",
                  ["sage/graphs/bliss.pyx"],
                  language="c++"),
                  libraries=['bliss'])
Reply all
Reply to author
Forward
0 new messages