tags:

views:

864

answers:

6

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.)

A: 

Probably not what you're thinking, but how about writing a stand-alone C++ program that the perl program communicates through pipes with?

Paul Tomblin
That's my backup plan.
Bill the Lizard
+2  A: 

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.

Mr Fooz
+3  A: 

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:

Adam Bellaire
+5  A: 

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.

Corion
+3  A: 

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();
}

}
dicroce
A: 

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.

daotoad