Re: Running a C Program within Perl.
by Sniper (Scribe) on Dec 27, 2001 at 20:56 UTC
|
You could use Inline.pm by Brian "Ingy" Ingerson
examples : http://www.perl.com/pub/a/2001/02/inline.html
module : http://www.cpan.org/modules/by-module/Inline/
use Inline C => <<'END_C';
void greet() {
printf("Hello, world\n");
}
END_C
greet;
Simply run this script from the command line and it will print (you guessed it):
Hello, world
David "Sniper" Rigaudiere
| [reply] [d/l] |
|
I am trying to run an external C program. I can run it fine from any Unix prompt, but when I put it into a perl program I get a long winded error, ending with "Directory" is not an identifier. Please help me I am very distraught.
| [reply] |
|
| [reply] |
|
Re: Running a C Program within Perl.
by vek (Prior) on Dec 27, 2001 at 20:56 UTC
|
Basically, there are three ways to run an external prog - 1 - system. 2 - backticks. 3 - open a pipe.
system:
my $cmdToRun = "/path-to/the-c-prog";
system ($cmdToRun) && die "system $cmdToRun - $!\n";
'system' just returns 0 on success and 1 on failure therefore you should test for it.
backticks:
my $cmdToRun = "/path-to/the-c-prog";
my @results = `$cmdToRun`;
Using backticks is useful if you need to capture output from the program you are calling.
pipe:
my $cmdToRun = "/path-to/the-c-prog";
open (CMD, "$cmdToRun |") || die "open $cmdToRun - $!\n";
while (<CMD>) {
# loop through the program output here...
}
UPDATE Of course this assumes you meant calling an external c prog from within perl. After reading sniper's post I realize you could have meant running actual c code from within perl - in that case Inline.pm would be the natural choice. | [reply] [d/l] [select] |
Re: Running a C Program within Perl.
by dmmiller2k (Chaplain) on Dec 27, 2001 at 20:59 UTC
|
It's not clear which of two things you are asking
- How to run an arbitrary external command line, which may or may not be the binary executable produced by compiling a C program.
- How to call C code (say, as a subroutine call) directly from perl.
The answer to the first question is simple and threefold:
- Run the command with back-ticks, assigning its STDOUT to a variable: as in, my $result = `commandline`;
- Use the system() function: as in, my $rc = system("commandline > result.log");
- Open the command as a pipe (if, say, you expect lots of output):
# note vertical bar (pipe) at end of command
open PH, "commandline|" or die "commandline: $!";
while (<PH>) {
# ... do something with each line of output
}
close PH or die "commandline: $!";
The answer to the second question is too involved to cover adequately here, but has been covered in depth elsewhere, among which are this and this.
Update: Another option, as posited by Sniper, is of course to use Inline.pm, but once again, that's a whole 'nother ball of wax.
dmm
You can give a man a fish and feed him for a day ...
Or, you can teach him to fish and feed him for a lifetime
| [reply] [d/l] [select] |
Re: Running a C Program within Perl.
by dmmiller2k (Chaplain) on Dec 27, 2001 at 22:15 UTC
|
(I have made this a reply to your original post; to continue the original thread would have indented too far for my taste)
I can run this at the prompt, but putting in the following, /opt/BIPSConnect/bin/rdes, but when I put it in perl code (here is what I am trying to do - Quite simple and nothing complex, until I get this working) ...
#!/usr/bin/perl-Tw
use strict;
my $cmd_to_run = "/opt/BIPSConnect/bin/rdes";
my @results = `$cmd_to_run`;
I get the following error...
/opt/BIPSConnect/bin/rdes: LD_LIBRARY_PATH=:/usr/lib:/usr/ucblib:/usr/openwin/lib:/usr/dt/lib:/usr/local/lib:/opt/hpnpl/lib:/p01cfg01/harvest/Harvest/lib:/opt/BIPSConnect/bin: is not an identifier
Okay, this is obviously a UNIX (not DOS/Windows) platform, so that eliminates an entire subspecies of problems.
I notice you are running your perl script with taint mode (-T). Are you, by chance, running it setuid, as well? In setuid mode Solaris (under which you appear to be running) closes the executable file and reopens it such that the program sees /dev/fd4 (or fd5, ...) instead of the name of the actual executable as $0, among other things. In taint mode Perl's behavior apropos the environment is somewhat different as well; certain specific variables must be set to known "safe" values (PATH and LD_LIBRARY_PATH come to mind, for example). Take a look at Perl security for more on this topic.
Update: Is it possible that the message you're seeing has something to do with trying to use the Bourne shell syntax,
[ENVVAR=value ...] command
with csh or tcsh, which do not permit this? What is your default shell?
Just asking ...
dmm
| [reply] [d/l] [select] |
|
Here is what rdes looks like.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/BIPSConnect/bin
/opt/BIPSConnect/bin/micn_cr2k_bips_test_console /home/w951an6/perl/ph
+ase_II/xxx.xml
does that help in knowing how to execute it? | [reply] [d/l] |
|
| [reply] |
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/BIPSConnect/bin
/opt/BIPSConnect/bin/micn_cr2k_bips_test_console /home/w951an6/perl/ph
+ase_II/xxx.xml
If that's the whole script, then you are missing the shebang line, i.e., #!/bin/sh, without which, Perl will attempt to execute it with your default shell, which (you didn't say) might be of the csh variety, not a Bourne-style (sh-like) shell.
Try putting a shebang as the first line.
dmm
| [reply] [d/l] [select] |
|
|
I got it working now.
by basicdez (Pilgrim) on Dec 28, 2001 at 01:22 UTC
|
Thanks to dmmiller2k and all of the others who helped me with this. The problem was that perl was looking for a bourne shell program and I was trying to run a korne shelle script. Once again, I will NOT make that mistake ever again. I feel both knowledgable and empowered. Thanks perl monks....
Happy new Year to everyone.
| [reply] |
|
| [reply] |
|
For the record, I think a lot of difficulty figuring out this problem stemmed from the fact that you kept referring to the target as a "C program" when it was in fact a shell script.
| [reply] |
Re: Running a C Program within Perl.
by hotshot (Prior) on Dec 27, 2001 at 20:30 UTC
|
You should run your C program as system call within your perl code:
system('/tmp/example.c');
# or
`/tmp/example.c` # back ticks
Hotshot | [reply] [d/l] |
|
| [reply] [d/l] [select] |
|
You are correct, but how do I do that?
| [reply] |
|
|
|