I am using python ctypes to call a function in c++ from python. Currently, I have the following c++ file:
five.cpp
extern "C" {
int get_five(){
return 5;
}
}
And python file:
five.py
import ctypes
from pathlib import Path
lib = ctypes.CDLL(Path(Path.cwd(),'five.dll').as_posix())
print(lib.get_five())
Which works and prints the number 5 when i run it.
However, as soon as I include any headers in the c++ file, it breaks down. So if I change the file to:
#include <iostream>
extern "C" {
int get_five(){
return 5;
}
}
It breaks, and I get the following error:
FileNotFoundError: Could not find module '...\five.dll' (or one of its dependencies). Try using the full path with constructor syntax.
I am compiling on Windows, with the following command:
g++ -shared five.cpp -o five.dll
I am probably missing something obvious, since I am very new to programming in c++. However, I can't seem to find what it is.
Related
I am trying to write a code that automate some of Nasa's Heasoft program - this doesn't matter -,
heainit is definied in the bashrc as:
export HEADAS=~/heasoft-6.27.2/x86_64-pc-linux-gnu-libc2.31
alias heainit='. $HEADAS/headas-init.sh
so whenever I write heainit on terminal it works pretty fine. However, whenever I tried to pass "heainit" to the terminal through c++ or Python, the code it self works but it doesn't initiate the program!
Ik that alise doesn't create an actual path there but i tried every possibility ik about.
in c++ I tried:
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <cstdlib>
#include <string>
#include <sstream>
using namespace std;
int main(int argc, char** argv){ string ind, outd;
const char* heainit = "/home/karim/heasoft-6.27.2/x86_64-pc-linux-gnu-libc2.31/headas-init.sh" ;
system(heainit);
return 0;
}
and
int main(string, char*){
string ind, outd;
std::string HEADAS = "/home/karim/heasoft-6.27.2/x86_64-pc-linux-gnu-libc2.31";
std::string str = std::string(". //") + HEADAS + std::string("/headas-init.sh");
const char *c = str.c_str(". /home/karim/heasoft-6.27.2/x86_64-pc-linux-gnu-libc2.31/heafas-init.sh");
system(const char* c);
return 0;
}
in python I tried:
import os
import subprocess
os.system("heainit")
subprocess.run("heainit",capture_output=True)
and
HEADAS=~/heasoft-6.27.2/x86_64-pc-linux-gnu-libc2.31
heainit="." + "\t" + HEADAS + "/headas-init.sh"
subprocess.run(heainit, shell=True)
My latest attempt was to write a bash script:
#!/bin/bash
export HEADAS=~/heasoft-6.27.2/x86_64-pc-linux-gnu-libc2.31
export HEADAS
alias heainit='. $HEADAS/headas-init.sh'
heainit
and the prompt gives the following: ./hea.sh: line 6: heainit: command not found
whenever I execute any of the aforementioned codes with anyother command like "ls -l" for instance it works perfectly :")) I don't know how should I pass this argument(it should be followed by others when the program is initiated) to the terminal yet and I don't know what i lack to go. Maybe the problem is trivial but i'm stuck there for a long time now.
whenever I tried to pass "heainit" to the terminal through c++ or Python, the code it self works but it doesn't initiate the program!
heainit is an alias. So first: the system call runs the shell in non-interactive mode in which alias is ignored and secondly: most probably you have an if [[ $- ~= *i* ]] on top of your bashrc to return when the shell is not interactive. In short: an alias is not a command and is meant to be run only in an interactive shell. bash shell manual aliases
If you wish to run heainit from the terminal, you could create an executable in PATH. Or you could create a function and add it to /etc/bash.bashrc before the interactive check or like to /etc/profile.d/*.
Still, that would most probably solve nothing, as the file is sourced. system() call and subprocess() runs a subprocess, the subprocess environment doesn't affect the parent environment. So if this assessment is true, sourcing the file is doing effectively nothing as it sources it in subprocess which doesn't affect the current environment. The solution would be to write a parser of the file (either a full blown shell parser and interpreter or something simpler depending on the content of the file) and parse the text from the file inside the current process.
I want to call a Python script from C, passing some arguments that are needed in the script.
The script I want to use is mrsync, or multicast remote sync. I got this working from command line, by calling:
python mrsync.py -m /tmp/targets.list -s /tmp/sourcedata -t /tmp/targetdata
-m is the list containing the target ip-addresses.
-s is the directory that contains the files to be synced.
-t is the directory on the target machines where the files will be put.
So far I managed to run a Python script without parameters, by using the following C program:
Py_Initialize();
FILE* file = fopen("/tmp/myfile.py", "r");
PyRun_SimpleFile(file, "/tmp/myfile.py");
Py_Finalize();
This works fine. However, I can't find how I can pass these argument to the PyRun_SimpleFile(..) method.
Seems like you're looking for an answer using the python development APIs from Python.h. Here's an example for you that should work:
#My python script called mypy.py
import sys
if len(sys.argv) != 2:
sys.exit("Not enough args")
ca_one = str(sys.argv[1])
ca_two = str(sys.argv[2])
print "My command line args are " + ca_one + " and " + ca_two
And then the C code to pass these args:
//My code file
#include <stdio.h>
#include <python2.7/Python.h>
void main()
{
FILE* file;
int argc;
char * argv[3];
argc = 3;
argv[0] = "mypy.py";
argv[1] = "-m";
argv[2] = "/tmp/targets.list";
Py_SetProgramName(argv[0]);
Py_Initialize();
PySys_SetArgv(argc, argv);
file = fopen("mypy.py","r");
PyRun_SimpleFile(file, "mypy.py");
Py_Finalize();
return;
}
If you can pass the arguments into your C function this task becomes even easier:
void main(int argc, char *argv[])
{
FILE* file;
Py_SetProgramName(argv[0]);
Py_Initialize();
PySys_SetArgv(argc, argv);
file = fopen("mypy.py","r");
PyRun_SimpleFile(file, "mypy.py");
Py_Finalize();
return;
}
You can just pass those straight through. Now my solutions only used 2 command line args for the sake of time, but you can use the same concept for all 6 that you need to pass... and of course there's cleaner ways to capture the args on the python side too, but that's just the basic idea.
Hope it helps!
You have two options.
Call
system("python mrsync.py -m /tmp/targets.list -s /tmp/sourcedata -t /tmp/targetdata")
in your C code.
Actually use the API that mrsync (hopefully) defines. This is more flexible, but much more complicated. The first step would be to work out how you would perform the above operation as a Python function call. If mrsync has been written nicely, there will be a function mrsync.sync (say) that you call as
mrsync.sync("/tmp/targets.list", "/tmp/sourcedata", "/tmp/targetdata")
Once you've worked out how to do that, you can call the function directly from the C code using the Python API.
The python script contains lots of libraries imported
My C code so far:
#include <stdio.h>
#include <python2.7/Python.h>
void main(int argc, char *argv[])
{
FILE* file;
Py_SetProgramName(argv[0]);
Py_Initialize();
PySys_SetArgv(argc, argv);
file = fopen("analyze.py","r");
PyRun_SimpleFile(file, "analyze.py");
Py_Finalize();
return;
}
Is there any other way that I can use so that even if any modification in arguments or number of python scripts I call inside c program increases the same code can be used with little changes?
Can I use system call and use the result obtained from it?
One useful way is calling a python function within c, which is that you need instead of execute whole script.
As described in
>> here
You can do like this to call the python file from the C program:
char command[50] = "python full_path_name\\file_name.py";
system(command);
This piece of code worked for me...
I didn't use # include < python2.7/Python.h>
You can write the results from the python file to any text file and then use the results stored in the text file to do whatever you want to do...
You can also have a look at this post for further help:
Calling python script from C++ and using its output
I am basically looking to see if it's possible to compile Python code into a C++ program such that a single binary is produced, then call the (compiled) python code as/with a function from within the C++ code.
Background: I have a C++ code that does some work and produces data that I want to plot. I then wrote a seperate Python script using SciPy that reads in the output data, processes it, and plots it to files. This all works as it is.
Basically, I am picturing:
void plotstuff() {
my_python_func(); // This is the python script compiled into the c++ binary
}
I don't need to pass anything between the python code and the C++ code other than being sure it's executed in the same directory. It may make things easier if I can pass string arguments, but again - not essential.
Can this be accomplished? Or is it generally a bad idea and I should just stick to having my C++ and python separate?
Yes: this is called embedding.
The best place to start is the official Python documentation on the topic. There's some sample code that shows how to call a Python function from C code.
Here's an extremely basic example, also from the Python docs:
#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;
}
Make a native extension (Python 2 or Python 3) out of your C++ code, and have your Python program import it. Then use py2exe or your favorite platform's counterpart to turn the Python program and your native extension into an executable.
I want to interface between Python and C++. I am trying to initially do it in simplest case, e.g. to find mean. My main is in python
1)Function getInput (python)
2)Function CalculateMean(C++)
3)Function DisplayMean(python)
My python file (main.py) looks like this:
function getInput(x,y)
//Here I want to add the function CalculateMean written in cpp file
function displayMean(m)
"CalcMean.h"
int CalculateMean(int x,int y)
"CalcMean.cpp"
mean = CalculateMean(x,y)
{
mean = (x+y)/2;
return mean;
}
I have tried using SWIG, but I am a begineer and unable to solve it. Any basic help will be highly appreciated.
you need a simple swig interface file that imports your CalcMean.h and produces a module, something like this into a mymodule.i file:
%module mymodule
%{
#include "CalcMean.h"
%}
%include "CalcMean.h"
then you can launch swig with something like
./swig -python -o mymodule.o mymodule.i
this will produce a .o file to be compiled as an .so/.dll file, as well as the required .py file to import the module.