writing get_script as an external routine callable by C

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View

With forum help, I've been able to do pretty good damage with using perl
for input.  It's *so much* easier than my alternatives with compiled
languages that I really feel like I'm in touch with the virtue of laziness.

I'm simply too immature with perl to, say, populate a binary tree with the
data or do many of the things that I can do with compiled languages, once I
have the data where I want it.  This is, I think, a nice final touch by
Mark Krahn:

# perl m13.pl  
use warnings;
use strict;

# open input file
my $filename = 'text43.txt';
open(my $fh, '<', $filename) or
  die "cannot open $filename for reading: $!";

# open output file
my $filename2 = 'outfile16.txt';
open(my $gh, '>', $filename2) or
  die "cannot open $filename2 for writing: $!";

local $/="";

while ( <$fh> )
  my ( $verse, @s ) = split;
  my $script = join ' ', @s;
  print $gh "$verse $script\n";

# close input and output files
close($gh) or die("Error closing $filename2: $!");
close($fh) or die("Error closing $filename: $!");

# abridged output:

44:004:002 Being grieved that they taught the people, and preached through
Jesus the resurrection from the dead.
44:004:003 And they laid hands on them, and put them in hold unto the next
day: for it was now eventide.
44:004:004 Howbeit many of them which heard the word believed; and the
number of the men was about five thousand.
44:004:005 And it came to pass on the morrow, that their rulers, and
elders, and scribes,

So now I want main to have to call a routine to get the next $verse and

@anything = get_script( $verse, \@s)

sub get_script

  my ( $verse, @s ) = split;
  my $script = join ' ', @s;
  return something;

Not exactly beautiful code, but my first efforts rarely look nice.  The
reference for this in the camel book is 6 : Passing References.  p 224

Then there's the matter of calling a perl subroutine from C.

#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char ** env)
  char *args[] = ;
  my_perl = perl_alloc();
  perl_parse(my_perl, NULL, argc, argv, NULL);
  call_argv("get_script", args);

  return 0;

The reference here is 21 of the camel book, p. 540.

Does any of this look close?

Oh, What Doesn't Kill You Can Have Lingering Aftereffects!
~~ Al Franken,

Re: writing get_script as an external routine callable by C

Quoth frank@example.invalid:
Quoted text here. Click to load it

Your sub (supposedly) takes a scalar and an array, but you are calling
it with a scalar and an arrayref. You need to decide which you want :).

What do you expect 'split' to do here? With no arguments it will split
$_ on whitespace, which means you will be using whatever value happens
to be in $_ at the time. I suspect you meant @_, which holds the
arguments passed to the sub.

Quoted text here. Click to load it

    return something;

is not valid Perl. It will compile if you don't have 'use strict' turned
on, but it won't do what you expect. This is (part of) the reason why
you should always have 'use strict' turned on until you know better.

Quoted text here. Click to load it

If you actually want to pass a ref, your sub needs to look more like

    sub get_script {
        my ($verse, $sref) = @_;
        my $script = join " ", @$sref;

Quoted text here. Click to load it

You haven't yet explained why you're trying to do this. Given your
inexperience with perl, it's almost certainly going to be easier to
stick with writing in one language at a time for now.

Quoted text here. Click to load it

Did you try to compile this? call_argv takes three arguments. Also, your
Perl sub is expecting at least two, and you haven't passed any Perl

Quoted text here. Click to load it

Reasonably so. You should be using perldoc perlembed as your reference
rather than the Camel book: the Camel was published shortly before the
release of perl 5.6.0, and a lot has changed since then. Most
importantly, you are missing PERL_SYS_INIT3 and PERL_SYS_TERM which must
be called first and last respectively.

You should also be aware that there are a number of undocumented
initializations that may or may not be necessary depending on your
platform. You can print a C file which ought to reproduce your current
perl binary by running

    perl -MExtUtils::Miniperl -ewritemain

Perl embedding is quite subtle, and I would not really recommend it
until you are familiar with writing XS. In order to do anything useful
with the embedded interpreter, you will need to know how to use the perl
API to get at and interpret the Perl values in the program.

You are passing main's argc/v to perl_parse, which means your program
will need to be called with the same command-line arguments as perl
would be. If you want your C program to run a particular Perl program,
you will need to create your own argv array to pass to perl_parse. Note
that you must still pass main's argc/v/env to PERL_SYS_INIT3.

If you really want to try this, you need to start by reading perlembed
and perlcall, and then probably perlapi and perlguts.


Re: writing get_script as an external routine callable by C

In Dread Ink, the Grave Hand of Ben Morrow Did Inscribe:

Quoted text here. Click to load it

[snipped and reordered]
Quoted text here. Click to load it

With that amount of reading in order to embed perl into C, I'll put that on
the reading list for my next injury.  Thank you.

Quoted text here. Click to load it

I've been reading 6.  The semantics section does not include an example
with inputs.  I think the best example is in Tricks with Parameter Lists
with something like:

sub get_script {
  my($verse, $script) =@_;

I was thinking that I would try to--thereafter--get these data in a hash,
which is close as I'm going to able to come to getting them into a tree.  I
suppose a hash is a tree, why not?

Anyways, below I see
sub configuration {
  my %options = @_;

Quoted text here. Click to load it

Ok, so a little more of the same terminology with @_ .  How does one
pronounce this symbol?

If main were going to open my_file and get the $verse and $script that
we've been using and calls get_script with

getscript($verse, $script);

and instead have:

sub get_script {
  my %options = @_;

, what will %options look like?  Could you print the hash in alphabetic
order?  Can you search in blindingly-fast time for a particular chapter and
verse, indicated by the obvious interpretation of $verse?

When you encounter seemingly good advice that contradicts other seemingly
good advice, ignore them both.
~~ Al Franken,

Site Timeline