How to call a large python script in C++? - python

I am trying to take aspects of two different scripts and use them in a single C++ program (using Ubuntu). The problem I have is that one of the scripts is written in C++ and the other is written in python. I have been trying to accomplish this using the Python.h library, but (being fairly new to programming), I cannot find any resources that would allow me to open the python file in C++. Does anyone have any suggestions?
As an example, I want to do something like the following:
#include <python2.7/Python.h>
//include other stuff
int main (int argc, char *argv[])
{
//open python script here
//use result from python script here
}
Thanks!

You should use popen, it pipes stdin/stdout of child process to returned file handle. Now what you can do is
File* in = popen("python script_name.py", "r");
Now you can use this FILE* to read the output of your python script.
Than you can use fscanf(in, buffer_size, buffer) of fgets(buffer, buffer_size, in) to read from file. Finally after reading from file don't forget to call pclose(in).

Related

How can I pass variables from Python back to C++?

I have 2 files - a .cpp file and a .py file. I use system("python something.py"); to run the .py file and it has to get some input. How do I pass the input back to the .cpp file? I don't use the Python.h library, I have two separate files.
system() is a very blunt hammer and doesn't support much in the way of interaction between the parent and the child process.
If you want to pass information from the Python script back to the C++ parent process, I'd suggest having the python script print() to stdout the information you want to send back to C++, and have the C++ program parse the python script's stdout-output. system() won't let you do that, but you can use popen() instead, like this:
#include <stdio.h>
int main(int, char **)
{
FILE * fpIn = popen("python something.py", "r");
if (fpIn)
{
char buf[1024];
while(fgets(buf, sizeof(buf), fpIn))
{
printf("The python script printed: [%s]\n", buf);
// Code to parse out values from the text in (buf) could go here
}
pclose(fpIn); // note: be sure to call pclose(), *not* fclose()
}
else printf("Couldn't run python script!\n");
return 0;
}
If you want to get more elaborate than that, you'd probably need to embed a Python interpreter into your C++ program and then you'd be able to call the Python functions directly and get back their return values as Python objects, but that's a fairly major undertaking which I'm guessing you want to avoid.

Call function from python in C++

I'm currently working on a project with a separate cli and gui. The gui part is written in C++ to keep the exectuable small. I compiled my python program with pyinstaller and need to call some functions from the C++ program.
Python part:
import configparser
def getconfig() -> list:
config = configparser.ConfigParser()
config.read("config.ini")
section1 = config["general"]
section2 = section["section2"]
return [section1, section2] #should be a list of dict?
Compiling it via pyinstaller --onefile --clean myprogram.py
What i would like to do in C++ is :
//please correct me if this is the wrong type,
//i know i probably need to do a bit of parsing between python and C++ types
std::vector<std::unordered_map<std::string, std::string>> > = myprogram.getconfig()
I just don't want to do the config parsing in C++ again, or would you recommend this as it's probably easier to call the compiled python binary?
This program just needs to run on linux, windows is not necessary.
If you are only planning to run on POSIX-compatible systems (ie. GNU/Linux), you could spawn a new process to run the Python script, e.g. using the C function exec. Example:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main()
{
char* args[] = { "pythonscript.py", NULL };
int t = execv("pythonscript.py", args);
if(t < 0) printf("%s\n", strerror(errno));
return 0;
}
And then in pythonscript.py:
#!/usr/bin/python3
print("hello, world!")
This trick works with bash scripts as well.
The script must be executable though, so remember to run chmod +x pythonscript.py.
EDIT:
You will likely need to use pipes or other mechanisms for inter-process communication. (this is not my expertise!)

How to use a script to control the program's input?

I need to control the input of a simple program written in C. I'm working on a Linux virtual machine (it's a computer security challenge) and I'm using GDB to find a good exploit (in this case it's a buffer overflow).
Here's the code:
static const char KEY[] = "BLOCKCHAIN";
void vuln(){
int i;
char buffer[616];
int output = fread(buffer, 1, 4*1024, stdin);
for (i = 0; i < 616; i++) {
buffer[i] ^= KEY[i % sizeof(KEY)];
}
printf("%s\n", buffer);
}
int main(int argc, char *argv[]){
vuln();
exit(0);
}
The line I want to cover is int output = fread(buffer, 1, 4*1024, stdin);. Is there a way to control the input of that program (so the input stream) with a simple script? I want to do something like:
./vuln_program `python -c 'print("\x90"*923+"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh"+"\x48\xbf\xff\xff")'`
This works if It were an argument of the main but unfortunately I'm inside the vuln() function and can't do this. Professors suggested to use: Python's subprocess module, or read\write from\to a named pipe (mkfifo), or the process module of theuse the pwntools Python library but I don't know how to use them in this scenario.
Thanks in advance.
You can do something like
$ python -c "exploit code" | ./vuln
Everything generated by python will be in arguments not in stdin. If you need to pass something to stdin you need to do: ./vuln_program < file_with_stdin_data
it doesn't need python at all to put some defined data to input stream, you can have data in normal file.
You can use python subprocess module to communicate with your script. Then you need to create subprocess and write something to its stdin. Check for python doc this:
As #blinkofaneye said, the simplest solution is using $ python -c "exploit code" | ./vuln
If you have to do it inside GDB (like me) as already suggested in this question Run a python command with “run” on GDB, the trick is to enter GDB and than use "Here strings":
run <<< $(python -c "print('exploit code')")

Linking the output of a Python script to the input of a C++ program

My python script is outputting the values of an analogue to digital converter to the console of a Raspberry Pi. In order to manipulate this data, I need to send this output to the input of a C++ file. Should I wrap my python code as C++ and include it inside of the program, or is there an easier way of passing the data directly?
To pass such a small amount of data I would recommend using the bash pipe. It seems to be the easiest way.
python script.py | ./cpp_prog
My fist thought on this would be to embed your script into a C++ program. Python itself suggests this. This would be the cleanest way. So you can control, if and when you get new data from your ADC.
Short excerpt from the link:
The simplest form of embedding Python is the use of the very high level interface. This interface is intended to execute a Python script without needing to interact with the application directly. This can for example be used to perform some operation on a file.
#include <Python.h>
int
main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print 'Today is',ctime(time())\n");
Py_Finalize();
return 0;
}
The Py_SetProgramName() function should be called before Py_Initialize() to inform the interpreter about paths to Python run-time libraries. Next, the Python interpreter is initialized with Py_Initialize(), followed by the execution of a hard-coded Python script that prints the date and time. Afterwards, the Py_Finalize() call shuts the interpreter down, followed by the end of the program. In a real program, you may want to get the Python script from another source, perhaps a text-editor routine, a file, or a database. Getting the Python code from a file can better be done by using the PyRun_SimpleFile() function, which saves you the trouble of allocating memory space and loading the file contents.
And so on and so forth. This will guide you in your way. May your project be good =)
If you mean at runtime, probably the simpelst way is via a std::system call
From https://en.cppreference.com/w/cpp/utility/program/system:
#include <cstdlib>
#include <fstream>
#include <iostream>
int main()
{
std::system("ls -l >test.txt"); // execute the UNIX command "ls -l >test.txt"
std::cout << std::ifstream("test.txt").rdbuf();
}
Possible output:
total 16
-rwxr-xr-x 1 2001 2000 8859 Sep 30 20:52 a.out
-rw-rw-rw- 1 2001 2000 161 Sep 30 20:52 main.cpp
-rw-r--r-- 1 2001 2000 0 Sep 30 20:52 test.txt
And just run your python whatever instead.

Best way to call executable and get output in python

First a simple example to illustrate the situation. First the source .cpp that has been compiled into an executable:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
cout << "Hello World!" << endl;
return 0;
}
This file has been made into an exe. Now in python it is called as follows:
import subprocess
import sys
sys.path.append('C:\Foo\Bar')
output = subprocess.Popen("hello_world.exe", stdout=subprocess.PIPE)
print output.stdout.read()
So this works fine for calling the executable and returning an output from the standard output. The question is, is there any feasible way to perform this to return potentially large arrays? From what I understand this is basically like returning and reading a text file, which would be quite slow! While I know SWIG or Cython are options for extending python with C++, I would find separate executable for each function more organized and modular!
TLDR: Can you return large arrays from executables back to python at a reasonable speed? Or is extending with Cython/SWIG/ctypes the only way to go?
You have two options.
subprocess.check_output or similar will return the entire program output as a string
subprocess.popen and incrementally read.
In the 1st scenario the output must fit in ram, otherwise very bad things will happen. In the second scenario you can set the buffer size and your subprocess should then halt until you read from the buffer at which point it will continue again.
cython/swig etc. etc. do nothing to reduce the memory footprint. If this is memory bound then you most likely want to use python and incrementally read/write to disk. Python is very efficient at passing around memory (i.e. it will not do eleventy seven memory copies unless you tell it to do that).

Categories

Resources