Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I call a C++ static library from Perl?

Tags:

c++

perl

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

like image 475
Bill the Lizard Avatar asked Jan 09 '09 14:01

Bill the Lizard


5 Answers

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.

like image 91
Corion Avatar answered Nov 18 '22 04:11

Corion


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:

  • perlxs
  • perlxstut
like image 25
Adam Bellaire Avatar answered Nov 18 '22 04:11

Adam Bellaire


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

}
like image 4
dicroce Avatar answered Nov 18 '22 04:11

dicroce


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.

like image 2
Mr Fooz Avatar answered Nov 18 '22 02:11

Mr Fooz


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

like image 1
Paul Tomblin Avatar answered Nov 18 '22 03:11

Paul Tomblin