I'm having a great deal of trouble using my c++ code from Visual C++ (wrapped by boost) in Python.
Alright, so the tools I'm using are: Visual Studio 2010, BoostPro 1_47, Windows 7, and Python 2.7 (32-bit).
I have the following code which compiles nicely in Visual Studio 2010:
#define BOOST_PYTHON_STATIC_LIB
#include <boost/python.hpp>
using namespace boost::python;
struct World
{
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
BOOST_PYTHON_MODULE(hello)
{
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set);
}
It's in the format: Win32 Console Application >>>Empty Project / DLL.
In "Project Properties":
VC++ DIRECTORIES:
I added:
>>> INCLUDE DIRECTORIES: C:\Program Files\boost\boost_1_47;C:\Python27\include .
>>> LIBRARY DIRECTORIES: C:\Program Files\boost\boost_1_47\lib;C:\Python27\libs
All of this makes the c++ file build but then I can't access it from Python.
This is what Python says when I try to use the module:
">>> import hello
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
import hello
ImportError: No module named hello
So I guess my question is... How can I get Python to find it???
When the c++ code compiles it creates a DLL file. Do I have to change the location of the file? If so, where should I put it?
Your help would be greatly appreciated
AFAIK you have to change the extension of the DLL to .pyd or otherwise Python will not be able to load it. I think you can set a build option to automatically set the extension in VS, but I don't know for sure.
Also, make sure that the created extension is somewhere on the PYTHONPATH, the path, python will look for modules to load.
Related
I used the visual studio installer to install python and could run the basic python program.
Now I want to make a new c++ console program and call the python script from there.
When googling I saw I need to include the "Python.h" in my c++ function. I tried to include and i get the message "cannot open the source file" . Is it because I used visual studio to install the python. And most of googling have installed python separately.
Older versions of visual studio, just installed python interpretter. So installed Visual studio 2019 and had a option to select Python3
With that option , it created a new directory, C:\Python27amd64\
Now I created a new console application:
Code:
#include <iostream>
#include "C:\Python27amd64\include\Python.h"
int main()
{
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is',ctime(time()))\n");
//std::cout << "Hello World!\n";
}
And also followed the following steps :
Properties > C/C++ > General > Additional Include Directories. I added the "C:\Python27amd64\include"
2.Properties > Linker > General > Additional Library Directories. : I added C:\Python27amd64\libs
3.Properties > Linker > Input > Additional Dependencies: I added python27.lib
I changed the build to "Release x64". Because it couldnot find the debug libraries
I have this C code i took from https://docs.python.org/3/extending/embedding.html:
#define PY_SSIZE_T_CLEAN
#include <Python.h>
int
main(int argc, char *argv[])
{
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("import numpy as np \n"
"student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])\n"
"print(student)\n");
if (Py_FinalizeEx() < 0) {
exit(120);
}
PyMem_RawFree(program);
return 0;
}
It compiles and runs quite nicely in a machine that has python3 and python3-numpy installed.
The output:
[('name', 'S20'), ('age', 'i1'), ('marks', '<f4')]
However, if the target machine does not have numpy installed, the output is:
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'numpy'
My question: is it possible to run the python code from the app executable in a target machine that has no Python3 nor numpy installed? If so, how do i do it?
I mostly thinking of Win10 as a target machine, but i guess my question would equally apply to other OSes.
Thanks!
EDIT: To be more exact, I am not asking if this code can be compiled without having Python installed. I know it must have some python-dev to be compiled.
But what I want to know is there a way to create an .exe file that uses some Python calls without having Python installed in the target machine?
Use PyInstaller. It will wrap your Python code, a Python interpreter, and the packages you need into a standalone .exe file.
Specifically, numpy is on the list of supported packages.
I would get rid of the C program, put your main Python code in a .py file, and let PyInstaller do the work for you.
This is a much better solution than requiring your users to have a Python interpreter installed, much less any particular libraries and packages. It allows each application to have its own version of Python and packages.
Full details are in the PyInstaller docs.
Im currently trying to write a c++ extension to python and only have a little bit of c++ code so far ... just to test the workflow/compilation.
#include "conservation.h"
#include <pybind11/pybind11.h>
double calculateMomentum(double mass, double velocity) {
return mass * velocity;
}
PYBIND11_MODULE(conservation, m) {
m.doc() = "Conservation-quantity calculator";
m.def("calculate_momentum", &calculateMomentum, "Returns Momentum of given parameters");
}
Then i create a makefile with the following configuration:
cmake_minimum_required(VERSION 3.4...3.19)
project(Calculation LANGUAGES CXX)
set(pybind11_DIR $CACHE{pybind11_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../extensions)
find_package(pybind11 REQUIRED)
pybind11_add_module(conservation ./src/calculation/conservation.cpp)
Afterwards i can compile the extension without any problem on Windows and Linux (using mingw32-make and make respectively)
When I try importing it in Linux it works without any problems or issues and I can run the calculate_momentum function.
But when I try importing the extension on a Windows machine I get the following Error:
ImportError: DLL load failed while importing conservation: The parameter is incorrect.
I'm not a very experienced user of cmake or pybind11 so it is entirely possible that I am doing something completely wrong and any input would be very much appreciated.
I am trying to reproduce the Boost.Python tutorial on how to do a wrap a C/C++ file for python.
This is the cpp file which builded successfuly.
#include "boost/python.hpp"
class SaySomething
{
public:
void set(std::string msg)
{
this->msg = msg;
}
std::string greet()
{
return msg;
}
std::string msg;
};
BOOST_PYTHON_MODULE(SaySomething)
{
namespace python = boost::python;
python::class_<SaySomething>("SaySomething")
.def("greet", &SaySomething::greet)
.def("set", &SaySomething::set)
;
}
In the same directory of the source code I have the python file
import SaySomething
msg = SaySomething.SaySomething()
msg.set('howdy')
msg.greet()
When I try to run the python file this error occurs
ModuleNotFoundError: No module named 'SaySomething'
I tried moving the compiled library to the same folder with no success. The tutorial doesn't elaborate on how to make the C++ file seen by the interpreter.
Edit
As some have suggested I have edited the extension of the compiled shared library to .pyd so python can see it. This creates a second error
ImportError: DLL load failed: The specified module could not be found.
This issue is exactly like mine. The solution suggests to add Boost.python to environnement variable. I know how to add path to this but I'm not sure what path I want, the boost.python dlls (or lib)? Just boost?
I basically did the same as the person here:
Building/including Boost.Python in VS2013
However, I used an empty cpp file with only the main function and the inclusion of <boost/python.hpp>
#include <boost/python.hpp>
int main() {
return 0;
}
Now I get the strange linker error (in Visual Studio):
1>LINK : fatal error LNK1104: cannot open file 'boost_python-vc140-mt-gd-1_60.lib'
Which is strange, because I have the lib file I think, however, it is called:
libboost_python3-vc140-mt-gd-1_60.lib
You need to configure your Visual C++ project setting.
The following case operates well.
[debug platform mode] x64
[include directory] (..\;;);C:\boost\boost_1_60_0\;C:\Python35\include\; # add your actual boost and python directory path
[library directory] (..\;;);C:\Python35\libs\;C:\boost\boost_1_60_0\stage\lib; # add your actual boost and python library path