2

I am calling executable file with main() function from php script using exec(). Which works fine but return all printf() values rather only returning array:

main.cpp:

#include<stdio.h>
#include<string.h>
#include "foo.h"
int main(int argc, char *argv[] )
{
    char buffer[1024];
    char *ch;
    static int ar[2];
    strcpy(buffer,argv[1]);
    printf("Client : \n");
    if ( argc != 2 ) /* argc should be 2 for correct execution */
    {
              printf( "\n%s filename\n", argv[0] );
    }
    else 
    {
        printf("\nstring is :%s \n",buffer);
    ch=foo(buffer);
    ar[0]=((int*)ch)[0];
    ar[1]=((int*)ch)[1];
    printf("Counts is :%d  %d \n",ar[0],ar[1]);
    }
    return (int)ar;

}

my test.php

<?php
$s="critic worst";
escapeshellarg($s);
$a=array(shell_exec('/home/technoworld/Videos/LinSocket/client "nice bad"'));
print_r($a[0]);
//echo exec('whoami');
?>

Which shows output:

Client : string is :nice bad Positive count: 2 Negative count: 2 array item2 2 Count is :2 2

I also tried with exec() which also gives same prob. Can any one suggest how to get ar[0] and ar[1] from main.cpp?

Client : string is :nice bad Positive count: 2 Negative count: 2 array item2 2 

This is from all printf() present in foo.cpp file.

When I use exec() then it gives Count is :2 2

How to get exact ar[0] and ar[1]

3 Answers 3

2

Perhaps simply

preg_match('/[0-9]*/', $output, $matches);

If I'm not mistaken...

To be sure:

preg_match('Counts is :([0-9]*)[^0-9]*([0-9]*)/',$output,$matches);

Also have a look at this question to find ouy how to use PHP and C(++) interactively

A quick, and hacky ugly messy workaround could be:

printf("%d",ar[0]);
return ar[1];//end main function

Then, in your PHP script:

$a = array(shell_exec('/home/technoworld/Videos/LinSocket/client "nice bad"'),
           shel_exec('echo $?');
);

Then get the last numeric value from the output string, (preg_match('/([0-9]*)\w*$/',$a[0],$matches); should do it, and $a[1] will contain the value of ar[1] of the main.cpp file, because that was the exit code. Note that exit codes aren't for show. The signify something! Changeing them is generally a bad idea. I'd just change my main.cpp, and add the line:

printf("@ar[0]=%d;ar[1]=%d@",ar[0],ar[1]);

This prints a clearly formatted string, which is easy to parse using a regular expression. Assuming *ar held values 123 and 456 respectively:

preg_match_all('/\]\=([^;@]*)/',$a[0],$matches);
var_dump($matches[1]);//[123,456]

Or better stil:

$parts = explode('@', $a[0]);
echo $parts[1];//ar[0]=123;ar[1]=456

Bottom line:

Add this to your main function in main.cpp:

printf("@ar[0]=%d;ar[1]=%d@",ar[0],ar[1]);

and, to get the int values in php:

$a = array(shell_exec('..'));
preg_match_all('/[^=]*\=([^;@]*)/',$a[0],$matches);
var_dump($matches[1]);

That should do it.

$a = array();
$b = array();
if (preg_match_all('/[^=]*\=([^;@]*)/', shell_exec('your command'), $matches))
{
   $a[] = (int) $matches[1][0];//optionally cast to int
   $b[] = (int) $matches[1][1];
}

That's all... not sure why $a and $b need to be arrays, but that's probably because you're going to call the client bin a couple of times.

Sign up to request clarification or add additional context in comments.

24 Comments

@user174889: Well, you can't access the stack of your program through a php script. You just can't. You'll either have to write a function like void getAr(int idx){ printf("%d", ar[idx]);}, where *ar needs to be in scope, obviously... or you're going to have to parse the main functions output
@user174889: You've got several issues: (int) ar; is casting a pointer to an int (don't ignore the compiler warnings). The regex I provided parses the output of the main function already. Accessing the return value of the shel_exec is easy on *NIX systems: change the command to '(your command here) && echo $?', since echo $? echoes the exit code of the last executed program, which is the int returned by int main, that should yield what you need
@user174889: Updated my answer. Don't use exit values, and the cast will still be wrong. You'll also need the parentheses,I think. PHP and shel_exec can do weird things if you combine several commands
@user174889: I'm sorry, but sometimes the answer you get isn't the answer you were hoping for, but PHP doesn't allow you to access stack memory that was allocated by another program. You can't access a C(++) function from PHP you just can't. If you refuse to accept that, then no answer to your question will ever get accepted.
@user174889: I don't know for sure, I don't know what you're actually doing. But if you have the int values printed out as I suggested @ar[0]=%d;ar[1]=%d@, then /[@;][^=]*\=([^;@]*)/ is a pretty solid expression, that'll match negative, positive, and (if in due time it'd be a requirement) floats or even strings can be parsed
|
2

Thanks to Elias for help. This is the solution:

<?php

if (preg_match_all('/[^=]*\=([^;@]*)/', shell_exec('/home/technoworld/Videos/LinSocket/client "nice bad worst good"'), $matches))
{
   $x = (int) $matches[1][0];//optionally cast to int
   $y = (int) $matches[1][1];
   echo $x. '<br/>'. $y. '<br/>'
}

?>

$x,$y contain ar[0] and ar[1] respectively

Comments

1

This will also work:

if (preg_match_all('/[^=]*=([^;@]*)/', shell_exec("/home/technoworld/Videos/LinSocket/client '$s'"), $matches)) //Values stored in ma.
{
    $x = (int) $matches[1][0];  //optionally cast to int
    $y = (int) $matches[1][1];
}

echo "<br/>"; echo "Positive count :$x";
echo "<br/>"; echo "Negative count :$y"; echo "<br/>";

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.