Calling function of an external Inline C block from another perl modules Inline C block

78 views Asked by At

I am looking for a way to call a function of an Inline C block present in a perl file from another file's Inline C block.

I have this perl file that contains the get_instrument_price function inside an Inline C block

package Dev::Instrument::Price;

use warnings 'all';
use strict;

use Inline C => <<'__END_OF_C__';

int get_instrument_price(int type)
{ return 154; }

__END_OF_C__

There's another file that should make a call to the above file to get the instrument price

package Dev::Instument::Detail;

use warnings 'all';
use strict;

use Inline C => <<'__END_OF_C__';

extern int *get_instrument_price(int type);

int get_instrument_detail(int type)
{ 
    # some code
    int instrument_price = get_instrument_price(type);
    # some more code
}

__END_OF_C__

I have tried using LIBS => '-L/_Inline/lib/auto' as mentioned in the references below that didn't work for me.

Took references from:

  1. Calling an external C function (in a shared lib) from Perl with Inline/C does not work
  2. https://www.foo.be/docs/tpj/issues/vol5_3/tpj0503-0005.html
  3. https://metacpan.org/dist/Inline-C/view/lib/Inline/C/Cookbook.pod
1

There are 1 answers

0
Håkon Hægland On

A workaround is to split the common C functions into a separate library, for example:

libinstrument/instrument.c:

#include "instrument.h"
int get_instrument_price(int type)
{
    return 154;
}

libinstrument/instrument.h:

int get_instrument_price(int type);

lib/Dev/Instrument/Detail.pm:

package Dev::Instrument::Detail;
use FindBin;
my $lib_dir;
BEGIN {
    $lib_dir = $FindBin::RealBin . '/libinstrument';
}
use warnings 'all';
use strict;
#use Inline Config => build_noisy => 1, clean_after_build => 0, print_info => 1;
use Inline C => config => libs => "-L$lib_dir -linstrument";
use Inline C => config => inc => '-I' . $lib_dir;
use Inline C => <<'__END_OF_C__';

#include "instrument.h"
int get_instrument_detail(int type)
{
    // some code
    int instrument_price = get_instrument_price(type);
    // some more code
    return instrument_price + 1;
}
__END_OF_C__
1;

lib/Dev/Instrument/Price.pm:

package Dev::Instrument::Price;
use warnings 'all';
use strict;

use FindBin;
my $lib_dir;
BEGIN {
    $lib_dir = $FindBin::RealBin . '/libinstrument';
}
use Inline C => config => libs => "-L$lib_dir -linstrument";
use Inline C => config => inc => '-I' . $lib_dir;
#use Inline Config => build_noisy => 1, clean_after_build => 0, print_info => 1;
use Inline C => <<'__END_OF_C__';
#include "instrument.h"

int foo(int type)
{
    int instrument_price = get_instrument_price(type);
    return instrument_price + 2;
}
__END_OF_C__
1;

p.pl:

#! /usr/bin/env perl
use v5.38;
use lib './lib';
use Dev::Instrument::Price;
use Dev::Instrument::Detail;

say Dev::Instrument::Price::foo(1);
say Dev::Instrument::Detail::get_instrument_detail(1);

Compile the common library:

$ gcc -shared -fPIC -o libinstrument.so instrument.c

Output:

$ perl p.pl
156
155