Calling C++ functions without headers.

188 views
Skip to first unread message

John Tyree

unread,
Jan 17, 2013, 6:47:36 PM1/17/13
to cython...@googlegroups.com
Hi everyone,

I am working with some C++ code and trying to call it from Cython. Not classes,
just functions.

The problem is that apparently using "cdef extern TYPE FNAME(ARGS)" is
restricted to the C calling convention. As a result, one is forced to make
trivial *.hpp headers that would otherwise be unnecessary.

I made a Gist with a sample setup demonstrating what I mean.
https://gist.github.com/4560948

I'd like to be able to specify cpp_good() directly in a.pyx somehow, but this
appears to be impossible without resorting to `extern "C"` wrappers around
everything. Has anyone else dealt with this?

- John

Robert Bradshaw

unread,
Jan 17, 2013, 11:18:44 PM1/17/13
to cython...@googlegroups.com
I think it's pretty standard to have .h files whenever you're trying
to use code from another library. If you just want to compile the
source with your extension, as you do here, forget the .h file and do

cdef extern from "b.cpp":
void cpp_good()
void cpp_bad()

rather than

# distutils: sources = b.cpp

John Tyree

unread,
Jan 18, 2013, 5:10:37 AM1/18/13
to cython...@googlegroups.com
Ah ok. I didn't realize it could be done this way. What's actually happening here? Are we directly including the source into cythons generated cpp?

Also for my own reference, is this the only way to access cpp functions?

John

John Tyree

unread,
Jan 18, 2013, 9:01:34 AM1/18/13
to cython...@googlegroups.com
Unless I've done something very wrong here, this doesn't actually work. Still gives linkage errors. Did this work for you?

Stefan Behnel

unread,
Jan 18, 2013, 9:08:41 AM1/18/13
to cython...@googlegroups.com
[fixed up reply order]

John Tyree, 18.01.2013 15:01:
> Le vendredi 18 janvier 2013 11:10:37 UTC+1, John Tyree a écrit :
>> Ah ok. I didn't realize it could be done this way. What's actually
>> happening here? Are we directly including the source into cythons generated
>> cpp?

Yes. C-including, that is, just like header files. You might want to look
at the generated C code.


> Unless I've done something very wrong here, this doesn't actually work.
> Still gives linkage errors.

The same ones as before? Could you post your latest code again?

Stefan

John Tyree

unread,
Jan 18, 2013, 11:21:32 AM1/18/13
to cython...@googlegroups.com
Ok. Building a test case illustrated my problem. The error was actually for
cpp_bad(), which *was* being declared twice with two different linkages.
Otherwise this appears to work fine.

There's no way to have namespaces come over with the function names is there?

cdef extern from "b.cpp" namespace "foo":
void whatever()

and then use foo.whatever() instead of just whatever()? I guess using a new pxd
for each namespace and then cimport namespace is the best solution to that problem.

John

On Fri, Jan 18, 2013 at 03:08:41PM +0100, Stefan Behnel wrote:
> [fixed up reply order]
>
> John Tyree, 18.01.2013 15:01:
> > Le vendredi 18 janvier 2013 11:10:37 UTC+1, John Tyree a �crit :

Robert Bradshaw

unread,
Jan 18, 2013, 1:54:24 PM1/18/13
to cython...@googlegroups.com
On Fri, Jan 18, 2013 at 8:21 AM, John Tyree <john...@gmail.com> wrote:
> Ok. Building a test case illustrated my problem. The error was actually for
> cpp_bad(), which *was* being declared twice with two different linkages.

Note that you'll probably want to build the library and link against
it to use it in multiple modules.

> Otherwise this appears to work fine.
>
> There's no way to have namespaces come over with the function names is there?
>
> cdef extern from "b.cpp" namespace "foo":
> void whatever()
>
> and then use foo.whatever() instead of just whatever()? I guess using a new pxd
> for each namespace and then cimport namespace is the best solution to that problem.

Yep. We could consider adding a "as XXX" clause to extern inport
blocks as well.

> On Fri, Jan 18, 2013 at 03:08:41PM +0100, Stefan Behnel wrote:
>> [fixed up reply order]
>>
>> John Tyree, 18.01.2013 15:01:

John Tyree

unread,
Jan 19, 2013, 10:11:13 PM1/19/13
to cython...@googlegroups.com
The as XXX alias on cdef extern from ... blocks would be seriously great. Would
it be difficult?

-John


On Fri, Jan 18, 2013 at 10:54:24AM -0800, Robert Bradshaw wrote:
> On Fri, Jan 18, 2013 at 8:21 AM, John Tyree <john...@gmail.com> wrote:
> > Ok. Building a test case illustrated my problem. The error was actually for
> > cpp_bad(), which *was* being declared twice with two different linkages.
>
> Note that you'll probably want to build the library and link against
> it to use it in multiple modules.
>
> > Otherwise this appears to work fine.
> >
> > There's no way to have namespaces come over with the function names is there?
> >
> > cdef extern from "b.cpp" namespace "foo":
> > void whatever()
> >
> > and then use foo.whatever() instead of just whatever()? I guess using a new pxd
> > for each namespace and then cimport namespace is the best solution to that problem.
>
> Yep. We could consider adding a "as XXX" clause to extern inport
> blocks as well.
>
> > On Fri, Jan 18, 2013 at 03:08:41PM +0100, Stefan Behnel wrote:
> >> [fixed up reply order]
> >>
> >> John Tyree, 18.01.2013 15:01:
> >> > Le vendredi 18 janvier 2013 11:10:37 UTC+1, John Tyree a �crit :

Stefan Behnel

unread,
Jan 20, 2013, 1:57:33 AM1/20/13
to cython...@googlegroups.com, Cython-devel
John Tyree, 20.01.2013 04:11:
> On Fri, Jan 18, 2013 at 10:54:24AM -0800, Robert Bradshaw wrote:
>> On Fri, Jan 18, 2013 at 8:21 AM, John Tyree wrote:
>>> There's no way to have namespaces come over with the function names is there?
>>>
>>> cdef extern from "b.cpp" namespace "foo":
>>> void whatever()
>>>
>>> and then use foo.whatever() instead of just whatever()? I guess using a new pxd
>>> for each namespace and then cimport namespace is the best solution to that problem.
>>
>> Yep. We could consider adding a "as XXX" clause to extern inport
>> blocks as well.
>
> The as XXX alias on cdef extern from ... blocks would be seriously great. Would
> it be difficult?

I'm -0.7 on this. It would divert from Python in that you'd get yet another
way to provide a namespace inside of one source file. It won't come for
free in terms of compiler code complexity. And I don't see the big win over
having one .pxd file per namespace that you declare. That's what files are
there for, after all. And it works the same in both Python and Cython,
right now.

Stefan

Robert Bradshaw

unread,
Jan 25, 2013, 3:13:46 AM1/25/13
to cython...@googlegroups.com
I agree that using separate .pxd files is both sufficient and more
pythonic. Perhaps I could be swayed given concrete examples of
libraries where this is overly burdensome.

- Robert
Reply all
Reply to author
Forward
0 new messages