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

Hello, all!

I'm trying to use the Perl Tk module to display data from an existing program. I've been able to call a Perl function from C and pass scalar and string data correctly, but I'm having problems with passing arrays by reference and with linking in the Tk and Class::Struct modules.

I can send the array address as an int and read the correct number within Perl, but all of my efforts to dereference it show an empty array.

Compiling the program with the Tk and Class::Struct invocations works, but it core dumps when I try to run it.

Does anyone have an example of how to do this? Given a set of code that works (passing an array by reference to a module), I'm sure I can figure out the details of my particular problem.

Thanks very much,

Diane.

  • Comment on Interfacing a C program with Perl functions and modules

Replies are listed 'Best First'.
Re: Interfacing a C program with Perl functions and modules
by Ovid (Cardinal) on Feb 18, 2004 at 19:37 UTC

    The following C code will return the array from an array reference.

    AV* get_array(SV* aref) { if (! is_array_ref(aref)) croak("get_array() argument is not an array reference"); return (AV*)SvRV(aref); } int is_array_ref(SV* ref) { if (SvROK(ref) && SvTYPE(SvRV(ref)) == SVt_PVAV) return 1; else return 0; } SV* get_element(AV* array, int index) { SV **temp; temp = av_fetch(array, index, 0); if (!temp) { printf("Could not fetch element %d from array", index); croak("Ending program"); } else return *temp; }

    Then, in another place in your C code you can use it like this:

    /* dereference array and get requested arrayref */ array = get_array(aref); elem = get_element(array, index);

    See AI::NeuralNet::Simple code for more information. I pass array references directly from Perl to C and back to Perl. I use Inline::C to make things easy.

    Cheers,
    Ovid

    New address of my CGI Course.

Re: Interfacing a C program with Perl functions and modules
by flyingmoose (Priest) on Feb 18, 2004 at 19:42 UTC
    I'm trying to use the Perl Tk module to display data from an existing program. I've been able to call a Perl function from C and pass scalar and string data correctly, but I'm having problems with passing arrays by reference and with linking in the Tk and Class::Struct modules.

    Maybe I'm wrong, but it seems easier (and more correct) to have the GUI program do one of the following: (1) Call C library functions directly, (2) Parse the output of the C program, or (3) Use IPC through pipes, sockets, memmap'd files, etc.

    This would leave your code a lot cleaner than tieing Perl and C together the hard way. If you have a C library you want to use and can tolerate having compilers required, Inline::C (which I've only just started to play with) is a joy to use...either way, it seems to make more sense (to me) to put the higher level language (in this case, Perl) on the top of the software stack and let it call the C, rather than the other way around.

      This would be simpler if I was writing the program from scratch. The problem is that this is an existing program, written by someone else, that is command-line-driven with a Unix-XWindows-C graphical interface to display data fitting results. I just want to replace the XWindows drawing utilities with something less platform-specific....

      To make things even more interesting, the calculation program is written in FORTRAN. I'm planning to use C wrapper functions to mesh the FORTRAN with the Perl rather than try to directly call Perl from FORTRAN. I'll stick to the existing function call format rather than muck around with the FORTRAN.

      Thanks,
      Diane.

        Sounds like it anyways. LANL, perhaps?