Testing Shared Libraries

     

Here's a secret: Perl's testing modules aren't just good for testing Perl. They can test anything you can call from Perl. With a little bit of help from a few other modules, it's easy to test shared libraries ”compiled C code, for example ”as if it were normal Perl code.


Note: You must have the Inline::C module installed and you must have a C compiler available and configured .

How do I do that?

Suppose that you want to test your C math library, libm . Specifically, you need to exercise the behavior of the fmax( ) and fmin( ) functions, which find the maximum or minimum of two floating point values, respectively. Save the following code as test_libmath.t :

 #!perl          BEGIN     {             chdir 't' if -d 't';     }          use strict;     use warnings;     use Test::More tests => 6;          use Inline C =>             Config   =>                     LIBS   => '-lm',                     ENABLE => 'AUTOWRAP'     ;          Inline->import( C => <<END_HEADERS );             double fmax( double, double );             double fmin( double, double );     END_HEADERS          is( fmax(  1.0,  2.0 ),  2.0, 'fmax(  ) should find maximum of two values'  );     is( fmax( -1.0,  1.0 ),  1.0, '... and should handle one negative'        );     is( fmax( -1.0, -7.0 ), -1.0, '... or two negatives'                     );     is( fmin(  9.3,  1.7 ),  1.7, 'fmin(  ) should find minimum of two values' );     is( fmin(  2.0, -1.0 ), -1.0, '... and should handle one negative'       );     is( fmin( -1.0, -6.0 ), -6.0, '... or two negatives'                     ); 

Run the tests with prove :

 $  prove test_math.t  test_math....ok     All tests successful.     Files=1, Tests=6,  0 wallclock secs ( 0.17 cusr +  0.01 csys =  0.18 CPU) 

What just happened ?

The Inline::C module allows easy use of C code from Perl. It's a powerful and simple way to build or to link to C code without writing Perl extension code by hand. The test starts as usual, changing to the t/ directory and declaring a plan. Then it uses Inline , passing some configuration data that tells the module to link against the m library ( libm.so on Unix and Unix-like systems) and generate wrappers for C functions automatically.


Note: Inline::C caches compiled code an_Inline/directory. The test file changes to t/to localize the cache in the test subdirectory .

The only C code necessary to make this work occurs in the import( ) call, which passes the function signatures of the C functions to wrap from the math library. When Inline processes this code, it writes and compiles some C code to create the wrappers from these functions, and then makes the wrappers available to the test as the functions fmax( ) and fmin( ) .

The rest of the test file tests some of the boundary conditions for these two functions.

What about...

Q:

Does this work with other languages besides C?

A:

There are Inline modules for various languages, including C++, Java, and PHP. The same or similar techniques work there too.

Q:

Can I achieve the same thing by using XS or SWIG to generate bindings?

A:

Absolutely. Inline is very easy for simple and moderate bindings, but it doesn't do anything that you can't do elsewhere.

Q:

Can Inline handle passing and returning complex data structures such as C-structs?

A:

Yes. See the Inline::C cookbook from the Inline distribution for examples.



Perl Testing. A Developer's Notebook
Perl Testing: A Developers Notebook
ISBN: 0596100922
EAN: 2147483647
Year: 2003
Pages: 107

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net