uwc has asked for the wisdom of the Perl Monks concerning the following question:

I have a C executable (linux) that I want to call a perl lib from. (this works) I want that perl lib to be able to call a C function in the exe. I have created the wrapper code for the perl->C i/f using SWIG. My problem is my perl library can't find the C code. How can I load the C symbol table so that perl knows where to call?

Replies are listed 'Best First'.
Re: C calling perl calling C
by kennethk (Abbot) on Apr 03, 2009 at 15:50 UTC

    This is usually done using XS. See perlxs and perlxstut for some instruction on implementation.

    An easier solution in your case may be to use the Inline::C module, which will autogenerate the XS wrapping for you.

Re: C calling perl calling C
by almut (Canon) on Apr 03, 2009 at 16:23 UTC

    Does your SWIG-generated Perl—>C binding work by itself? Is the Perl code loading the respective (shared) library that implements the binding? Have you linked against all required C libs? What's the exact error message you're getting?

    If you post some stripped-down sample code that demonstrates the problem, you might get more than hand-wavery and pointers to docs you're already aware of... :)

      .... somewhere in big C program
      void call_perl(void) { /* call perl function to do the work and trap any errors */ /* use the static (singleton) version of the perl interpreter */ my_perl = get_perl("module_init.pm");
      based on SWIGs' perlmain.i
      PerlInterpreter* get_perl(char *perl_file) { int exitstatus; /* have we done this? */ if (NULL != my_perl) { return my_perl; } char *my_argv[] = { "", perl_file }; my_perl = perl_alloc(); if (!my_perl) exit(1); perl_construct( my_perl ); exitstatus = perl_parse( my_perl, xs_init, 2, my_argv, (char **) N +ULL ); if (exitstatus) exit( exitstatus ); /* Initialize all of the module variables */ /* exitstatus = perl_run( my_perl ); */ return my_perl; }
      back to call_perl
      perl_call_pv("module::sub", G_EVAL|G_DISCARD|G_NOARGS|G_VOID) ;
      So far so good. I am now happily in perl land. next:
      c_exe::c_function($self->{value},$self->{channel});
      This fails. What should happen is the call gets routed through this bit of SWIG generated perl code
      package c_exe; *c_function = *c_exec::c_function;
      to this c file: c_exe_wrap.c
      XS(_wrap_c_function) { { BOW_USHORT arg1 ; BOW_UCHAR *arg2 = (BOW_UCHAR *) 0 ; unsigned short val1 ; int ecode1 = 0 ; int res2 ; char *buf2 = 0 ; int alloc2 = 0 ; int argvi = 0; BOW_SHORT result; dXSARGS; ... a bunch of code to validate parameters ... result = c_function(arg1,arg2); ... a bunch of code to handle return ... } }
      But what I get is something like:
      function c_exe::c_function not found at...
Re: C calling perl calling C
by uwc (Initiate) on Apr 03, 2009 at 22:34 UTC
    As I expected, I was very close. What I posted was basicly correct. I had to make a number of very small changes in various places to get things to work. But it now works.
      An update to your previous post would be nice. "Don't bogart that clue, my friend..." ;-)