Reputation: 405755
I'm writing a C++ static library that needs to be shared among several applications, one of them written in Perl. Unfortunately, I only barely know the core Perl language (I read the Llama book), and I'm not all that familiar with its libraries. How do you make calls to an external C++ binary from a Perl script?
By Google search, I found information on the Perl Inline module, but if I understand it correctly, that isn't what I need. I'm pretty sure that's for writing C and C++ code directly in your Perl scripts, not for calling external C++ libraries.
The C++ static library is being cross-compiled for an ARM processor, so there will be no C++ compiler on the target machine where the Perl script will be running. (If that makes a difference.)
Upvotes: 11
Views: 9259
Reputation: 27183
I'm only starting to wrap my head around XS, so I can't offer much help. But here's what I do know...
There is XSpp, which is XS for C++. It is distributed with WxPerl. WxPerl is under active and responsive development.
Inline:CPP can be used to write your initial interface/wrapper code. Then you can analyze the generated XS. However, it doesn't look so well maintianed. If it works, it may provide you with a good head start.
You might find this short note on XS and C++ by John Keiser helpful, if a bit dated.
Upvotes: 0
Reputation: 46770
First, it does need to be in a dynamic library, not a static library (unless you'll be re-compiling perl itself and linking it against your static library).
Second, since C++ will mangle the names (one of the most annoying "Features" of C++ if you ask me) you'll need an extern "C" block that contains hook functions. If you were using C++ you could probably get by with a single hook function that returns the C++ object that implements the interface you need to use. Since you're using perl, you may need to wrap an object in an interface like this:
CPPObject object; extern "C" { int InitObject( void ) { return object.init(); } int DoCoolStuff( void ) { return object.DoCoolStuff(); } int DoOtherCoolStuff( int foo ) { return object.DoOtherCoolStuff( foo ); } int DestroyObject( void ) { return object.Destroy(); } }
Upvotes: 4
Reputation: 507
You can call code from other libraries via Inline::C (and likely the same via Inline::CPP) - have a look at Inline::C::Cookbook. Most likely you want to start out with Inline and after you're done experimenting use the resulting .XS file to work further.
Upvotes: 8
Reputation: 110489
You want to look at using XS, which is how Perl normally interfaces with C/C++ libraries. It's not quite trivial. A couple of relevant portions of the Perl documentation:
Upvotes: 5
Reputation: 111856
You need to create a wrapper function that is callable from perl, and AFAIK, you'll need to have this wrapper function be in a dynamic library (unless you're going to rebuild the perl binary and link the static lib to it). I like to use a tool called SWIG (Simple Wrapper Interface Generator) to create the wrappers for me. It can create wrappers for 17 or so other languages too.
Upvotes: 2
Reputation: 182782
Probably not what you're thinking, but how about writing a stand-alone C++ program that the perl program communicates through pipes with?
Upvotes: 1