http://qs321.pair.com?node_id=1150902


in reply to Using module with c code in perl program.

Attempting to place the C code as a string directly into the benchmarking script, a new error was produced.

Error. You have specified 'C' as an Inline programming language. I currently only know about the following languages: Foo, foo If you have installed a support module for this language, try deleting + the config-xxx-xxx-xxx-5.020003 file from the following Inline DIREC +TORY, and run again: C:/Users/home/Desktop/.Inline (And if that works, please file a bug report.) at ./calcit.pl line 14. BEGIN failed--compilation aborted at ./calcit.pl line 14.

So it may be that there needs to be some further modules installed for Strawberry Perl to use Inline.pm with C.

Replacing END with DATA unfortunately still produces the original Error. I tried to open Inline::DATA as a file handle, but I couldn't quite apply IO calls to pseudo Handles. Also tried various permutations of the examples on C-PAN and in the Cookbook. See below for Code which produced new error. Also note Inline::Files did not install when I ran the cpan install Inline cmd

#!perl use strict; use warnings; use File::Spec::Functions qw/catfile/; use lib catfile('C:', 'Users', 'home', 'Perl5', 'lib', 'perl5' ) ; use Time::HiRes qw(gettimeofday tv_interval); #use Test::More; #use c_calc; #use perl_calc; use Inline C => '<<END_C'; double my_abs(double num) { return (num > 0)? num : -num; } double calc_pi() { double real_pi = 3.14159265358979; double my_pi = 0; double step_sign = 1; unsigned long long i = 1; while(my_abs(real_pi - my_pi) > 0.00000001) { my_pi += 4.0/i * step_sign; step_sign *= -1; i += 2; } return my_pi; } END_C my $start_time_c = [ gettimeofday ]; my $c_calc = calc_pi(); #c_calc::calc_pi(); my $end_time_c = [ gettimeofday ]; my $elapsed_c = tv_interval($start_time_c,$end_time_c); my $start_time_perl = [ gettimeofday ]; my $perl_calc = 3.14159 ** 2.71828; #perl_calc::calc_pi(); my $end_time_perl = [ gettimeofday ]; my $elapsed_perl = tv_interval $start_time_perl,$end_time_perl); my $differences = abs($elapsed_perl - $elapsed_c); #if(ok($c_calc == $perl_calc, "Pi number calc")) if($c_calc != $perl_calc) { print "C computation time = $elapsed_c\n"; print "Perl computation time = $elapsed_perl\n"; print "Differences = $differences\n"; } #done_testing;

Frustratingly, when no use of the DATA symbol occurs there are still attempts to read the unopened handle. Hope this helps progress the issue. DC.

Replies are listed 'Best First'.
Re^2: Using module with c code in perl program.
by stevieb (Canon) on Dec 21, 2015 at 22:40 UTC

    Out of curiosity, does quoting the requirement of Inline help? ie. use Inline 'C' ... I don't have access to Windows at the moment, so I can't test.

    For that matter, kind of goes without saying, but you can compile a C program outside of Perl in your setup, yes?

      the quoting does not make a difference. from the docs there are various ways of getting the code in. The problem seems to be more that the DATA handle is being read without being opened first.

      inside Inline, c_calc::DATA is aliased into Inline::DATA, and then read in after requiring Socket, but this is used just for CR and LF definitions. I hardcoded those definitions and commented out the Socket require, to no effect. then the subroutines goes on to read-in the aliased Inline::DATA. (my $data = <Inline::DATA>) =~ s/$CR?$LF/\n/g;

      I can compile a C program, using the gcc compiler which comes with Strawberry, I did so to ensure the C code was running before attempting to inline. This would indicate that I already have C compatibility from Strawberry, which makes the "not understanding C language" error contradictory.

Re^2: Using module with c code in perl program.
by Anonymous Monk on Dec 21, 2015 at 23:31 UTC
    Also note Inline::Files did not install when I ran the cpan install Inline cmd
    Did you actually install Inline::C, or just Inline (without ::C)?

      Ok, promising start, but then failed

      Inline::C was not installed. I installed Inline::C and the script with the code worked. I then tested the script with the C code in the module and that worked, firstly with the Test::More module being used, and then without the ok routine, and it worked. But then it did not continue to work.

      I'm just trying to recreate this now.

      ...

      The script with the Inline code embedded runs whether Testing is active or not.

      The Module import still does not open the DATA filehandle. Stepping through in db, Inline calls init which calls read_DATA, which requires Socket, so it jumps between Strict, Socket, Exporter, and XS_Loader. Then attempts the read on the unopened DATA filehandle.

      At this point I need to look a bit further in detail as to what is happening.

      For some reason there is an error when i tried to install Inline::C both on Ubuntu and Windows. So i was sent portable perl version with preinstalled Inline::C.