Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import C function into Perl program

Tags:

c

perl

I'd like to import a C function I wrote

#include <math.h>
#include <stdio.h>

double function (const double *restrict ARRAY1, const size_t ARRAY1_SIZE, const double *restrict ARRAY2, const size_t ARRAY2_SIZE) {//calculate a p-value based on an array
....
}
int main(){
....
}

into a perl script, I've seen Inline::C and XS but I don't see how to use them, I can't work through the examples, and I also need the lgamma function. The function takes 2 arrays as input.

Would anyone be able to provide an example of how I could import this into a perl script while importing C's math.h as well?

like image 847
con Avatar asked Feb 06 '23 14:02

con


2 Answers

The tricky part of this question is passing arrays of doubles from Perl to C.

One approach is to use two steps. Converting a Perl array (AV* in C) to a double array, and then calling your function. The perl functions and macros used here are documented in perlguts

use Inline 'C';
@a = (1,2,3,4,5);
@b = (19,42);
$x = c_function(\@a,\@b);
print "Result: $x\n";
__END__
__C__
#include <stdio.h>
#include <math.h>
double *AV_to_doubleptr(AV *av, int *len)
{
    *len = av_len(av) + 1;
    double *array = malloc(sizeof(double) * *len);
    int i;
    for (i=0; i<*len; i++)
        array[i] = SvNV( *av_fetch(av, i, 0) );
    return array;  /* returns length in len as side-effect */
}

double the_real_function(const double *x1, int n1, const double *x2, int n2)
{
    ...
}

double c_function(AV *av1, AV *av2)
{
    int n1, n2;
    double *x1 = AV_to_doubleptr(av1, &n1);
    double *x2 = AV_to_doubleptr(av2, &n2);
    double result = the_real_function(x1,n1, x2,n2);
    free(x2);
    free(x1);
    return result;
}
like image 140
mob Avatar answered Feb 16 '23 03:02

mob


Here's an example using Inline::C, while calling a function from math.h:

use warnings;
use strict;

use Inline 'C';

my $num = c_function(5, 5);

print "$num\n";

__END__
__C__

#include <math.h>
#include <stdio.h>

double c_function(int x, int y){
    return pow(x, y);
}

Output:

3125
like image 35
stevieb Avatar answered Feb 16 '23 02:02

stevieb