xsawyerx/xs-fun

Does it work with C++ too?

Closed this issue · 5 comments

I guess this is really a dumb question but do you have fun with XS and C++ too?
Because, I like the OpenFST library (http://www.openfst.org) and would love to see at least some bindings in Perl, but it's written in C++, not C.
XS fun in the other hand constantly talks about C++.

I would like to say "yes", but I'm not knowledgeable enough to know whether there would be a problem or where. @tsee would be probably know the answer without even hearing the question. :)

There might be an easier way to do this, but you could definitely compile a C++ object file with a few functions declared as extern "C", and then use those functions from within your XS file.

tsee commented

On 10/09/2014 10:44 PM, Sawyer X wrote:

I would like to say "yes", but I'm not knowledgeable enough to know
whether there would be a problem or where. @tsee
https://github.com/tsee would be probably know the answer without even
hearing the question. :)

I'm a tad pressed for time, but I can try to divine an answer to an
unspoken question next week. ;)

But the sure fire war to get an authoritative answer is to ask Mattia.
If it's mixing C++ with Perl, he basically invented it...

--Steffen

tsee commented

I'll try to write a bit of a better response before my wife gets back. :)

On 10/09/2014 08:05 PM, Alex wrote:

I guess this is really a dumb question but do you have fun with XS and
C++ too?
Because, I like the OpenFST library (http://www.openfst.org) and would
love to see at least some bindings in Perl, but it's written in C++, not C.
XS fun in the other hand constantly talks about C++.

Fundamentally, XS and C++ are perfectly compatible. Where you get
complications is:

a) The build system (which compiler will it use? Perl's compiled with a
C compiler and the toolchain knows nothing about C++). In this context,
ExtUtils::CppGuess may be useful if you're to start from scratch.

b) Mapping C++ objects to Perl objects (and C++ classes to Perl
classes). In practice, there's little C++ code without classes and
objects. Ultimately, the way this usually works is the same as how you
create OO Perl modules from C libraries that use structs for state.

c) Templates. There's no good syntax in Perl to expose C++ templates. :(

d) Ownership. This is actually the same as in C: If all you have is C
structs or C++ objects that are created and then exposed to Perl and
that are freed (deleted) when Perl decides to throw away the Perl-level
object, then all you need to figure out ownership is a "sub DESTROY" in
XS. But often, a C++ method will return another object. Now, it depends
on whether the C++ library's convention is that these objects are owned
by the parent object (whose method returned it) or by the caller. If
it's always the same for a class of objects, you're in luck. The case
where the parent object always owns the instances its methods return is
a bit icky (what if the parent is destroyed first? Need to prevent
that.) But if for the same instance type, sometimes they're owned by a
C++ object, and sometimes by you (as in Perl), then you end up having to
code a bunch of indirection that can be very annoying.

Again, d) is the same in traditional XS with C. But the problem is much
more common with C++ code.

I'm sure I'm missing stuff, though.

Now the good news. There's a bunch of tools that try to make exposing
C++ to Perl easier. They're all on_top_of XS, so I'd suggest learning
XS fairly well before barging ahead into those.

The core tool is the ExtUtils::XSpp[1](as in: XS++) module (that Mattia
wrote). It creates a new syntax that's inspired by C++ headers with some
additional annotations. From there, it generates the traditional XS that
will wrap your C++ classes.

ExtUtils::XSpp doesn't solve the build system problem ( a) above ). For
this, there's Module::Build::WithXSpp[2] which tries to make building
XS++ distributions easier.

And now, finally, I can point you at a tad easier a starting point.
Examples!

Example 1: simple XS++ distribution using Module::Build::WithXSpp:
https://metacpan.org/source/SMUELLER/ExtUtils-XSpp-0.18/examples/XSpp-Example

Example 2: simple XS++ distribution WITHOUT M::B::WXSpp:
https://metacpan.org/source/SMUELLER/ExtUtils-XSpp-0.18/examples/Object-WithIntAndString

Example 3: real world use cases in order of increasing complexity:
https://metacpan.org/release/Math-ThinPlateSpline
https://metacpan.org/release/Math-Clipper
https://metacpan.org/release/Math-SZaru
https://metacpan.org/release/Wx (which was the reason why Mattia
invented XS++ in the first place)

Hope this helps a bit.

Best regards,
Steffen

PS: @sawyer: If you think XS++ would be interesting/appropriate as a
learning thing in p5pclub at work, let me know. I'm sure Mattia would be
more than happy to contribute as well. Maybe too early, though?

[1] https://metacpan.org/pod/ExtUtils::XSpp
[2] https://metacpan.org/pod/Module::Build::WithXSpp

@tsee Thank you for the comprehensive response.

I don't know how many in the club are from a C++ background, and we're mostly focusing on understand the core itself, which is C. However, one meeting to cover how these interact will probably be of interest to everyone (myself included). If you have the time, we'd love to hear it.