How to print to Python terminal with Boost::Python - c++

I would like to do the equivalent of a print in python from a library I wrote in C++. I am using Boost 1.60.0 and Python 2.7.
I found the following sites :Mantid and WikiBooks. From what I understood this code should work, but nothing is printed.
cpp file
void greet()
{
std::cout<<"test_01\n";
std::cout<<"test_02"<<std::endl;
printf("test_03");
}
BOOST_PYTHON_MODULE(PythonIntegration)
{
def("greet", greet);
}
py file
import PythonIntegration
PythonIntegration.greet()
I checked if the function was called by making it return something and it works, but still nothing is printed.
Thank you for your help

This hello world example seems to do exactly what you want : https://en.wikibooks.org/wiki/Python_Programming/Extending_with_C%2B%2B
Basically...
C++
#include <iostream>
using namespace std;
void say_hello(const char* name) {
cout << "Hello " << name << "!\n";
}
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
{
def("say_hello", say_hello);
}
Now, in setup.py
#!/usr/bin/env python
from distutils.core import setup
from distutils.extension import Extension
setup(name="PackageName",
ext_modules=[
Extension("hello", ["hellomodule.cpp"],
libraries = ["boost_python"])
])
Now you can do this :
python setup.py build
Then at the python command prompt :
>>> import hello
>>> hello.say_hello("World")
Hello World!

Related

pybind11: RuntimeError for passing Numpy Array

I'm trying to get pybind11 to accept a 3D unsigned integer numpy array that can be u8, u16, u32, or u64. However, after compiling, I get a RuntimeError. I tried enabling detailed error messages, but no dice. Does anyone see my mistake here?
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#define PYBIND11_DETAILED_ERROR_MESSAGES
#include <vector>
#include "crackle.hpp"
#include "cc3d.hpp"
namespace py = pybind11;
py::tuple connected_components(const py::array &labels) {
return py::make_tuple(...);
}
PYBIND11_MODULE(example, m) {
m.doc() = "comments.";
m.def(
"connected_components",
&connected_components,
"Perform 4-connected components in layers on a 3D array."
);
}
At runtime:
results = example.connected_components(labels)
RuntimeError: Unable to convert call argument to Python object (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)
Here's my setup.py:
import setuptools
from pybind11.setup_helpers import Pybind11Extension, build_ext
ext_modules = [
Pybind11Extension(
"example",
["src/example.cpp"],
extra_compile_args=["-std=c++17"],
),
]
setuptools.setup(
setup_requires=['pbr'],
cmdclass={"build_ext": build_ext},
ext_modules=ext_modules,
pbr=True
)
I needed to also write:
#include <pybind11/stl.h>
Pybind11 couldn't convert a vector to a list without it.

Python debug shell in embedded environment: exec or eval?

I'm building an embedded python application in C++, using boost::python. The embedded environment exports part of itself as a module, in other words the python code that runs in the environment won't run in a standard python env as the embedded module can't be imported.
One of the features that would be really helpful for debugging would be a debug shell, where I can break out and manually input standard python expressions to inspect/modify the current state. The problem I have is that I don't/can't know in advance whether it's an eval (e.g. "2+2") or an exec (e.g. "a=2+2"). If I exec("2+2") I don't get the result, and if I eval("a=2+2") I get a syntax error. (Coming from a C background I don't quite understand why this distinction exists). Trying eval first, then exec if it fails, seems like a very dubious solution not least because of side effects.
As far as I can see boost::python simply replicates python's eval/exec functions, so this problem is more at the python level, but the answer I'm hoping to get is how to do it at the C++ (ideally boost) level. Is there some horrendously complicated regex that could be used to differentiate exec-able from eval-able code? For now I'm just going with the ugly solution of making the user decide with a prefix on the expression.
Here's an MCVE with a TODO at the point where I need to choose between eval and exec (obv. requires python-dev and boost_python libs)
// g++ $(python3-config --cflags) so.cpp -fPIC -lboost_python3 $(python3-config --ldflags)
#include <boost/python.hpp>
#include <string>
#include <iostream>
namespace py = boost::python;
std::string pyobject_to_string(PyObject* obj)
{
PyObject* repr = PyObject_Str(obj);
PyObject* str = PyUnicode_AsEncodedString(repr, "utf-8", "~E~");
const char *bytes = PyBytes_AS_STRING(str);
Py_XDECREF(repr);
Py_XDECREF(str);
return std::string(bytes);
}
int main(int argc, const char** argv)
{
// Init python env
Py_Initialize();
if (argc < 2)
{
return 1;
}
try
{
// TODO decide, based on argv[1], which needs to be called, this:
py::object res = py::eval(argv[1]);
std::cout << pyobject_to_string(res.ptr()) << std::endl;
// or this:
py::exec(argv[1]);
// or something else entirely...?
}
catch(py::error_already_set&)
{
if (PyErr_Occurred())
{
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
std::string message = pyobject_to_string(type) + ":" + pyobject_to_string(value);
//PyErr_Restore(type, value, traceback);
std::cerr << message << std::endl;
}
else
{
std::cerr << "unknown error" << std::endl;
return 1;
}
}
}
Example output is:
$ ./a.out 2+2
4
$ ./a.out a=2+2
<class 'SyntaxError'>:('invalid syntax', ('<string>', 1, 2, 'a=2+2'))
Many thanks in advance

Linking against libuv

I wanted to try using libuv in dlang. I downloaded the dlang bindings like this:
git clone git#github.com:tamediadigital/libuv.git
Now what I do next to get my "hello world" running?
I tried this:
ldc2 hello.d -luv
But it said:
ldc2: Unknown command line argument '-luv'. Try: 'ldc2 -help'
ldc2: Did you mean '-v'?
I think I need to tell the compiler where the library bindings are located.
And then import something in the source code, probably with import libuv;?
Here is the 'hello world' code I want to "port" to D:
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>
int main() {
uv_loop_t *loop = malloc(sizeof(uv_loop_t));
uv_loop_init(loop);
printf("Now quitting.\n");
uv_run(loop, UV_RUN_DEFAULT);
uv_loop_close(loop);
free(loop);
return 0;
}
Here is the bindings github page: https://github.com/tamediadigital/libuv
Library home page: http://www.libuv.org
First that was a wrong bindings, here are the good ones: https://github.com/changloong/libuv
Assuming you did git clonegit#github.com:changloong/libuv.git in current dir.
Compile:
ldc2 hello.d -I=libuv/deimos/libuv/ -I=libuv/ -L=-luv
The source:
import uv;
import core.memory;
import std.stdio;
int main(){
uv_loop_t *loop = new uv_loop_t;
uv_loop_init(loop);
printf("Now quitting.\n");
uv_run(loop, uv_run_mode.UV_RUN_DEFAULT);
uv_loop_close(loop);
return 0;
}
Hope it helps someone to get started with using C libs in D.

Using numpy on an embedded python interpreter using VS2008 under Windows 7

Let's take a look at my project.
I'm using Visual Studio 2008, Python 2.7 and numpy 1.8.1 (but I have tried several versions and none worked). My project is being compiled on debug mode.
It's a very simple code:
/* = Main.cpp file = */
#include "stdafx.h"
#include "Python.h"
int _tmain(int argc, _TCHAR* argv[])
{
PyObject *pName, *main;
Py_Initialize();
pName = PyUnicode_FromString("main");
main = PyImport_Import(pName);
Py_XDECREF(pName);
if (main != NULL)
{
printf("Python Module Loaded!!\n");
}
else
{
printf("Unable to load Python Module!!\n");
}
return 0;
}
And
""" = Main.py file = """
print 'Hello World!'
If I execute this code, I get:
As it is expected.
My problem arises as soon as I change main.py into:
""" = Main.py file = """
import numpy
print 'Hello World!'
Then I get the:
I have tried to run main.py separately on a python interpreter (not embedding it into C++) and then everything works just fine:
I have also tried a modification on the main.cpp as follows:
#include "stdafx.h"
#include "Python.h"
int _tmain(int argc, _TCHAR* argv[])
{
PyObject *pName, *main;
Py_Initialize();
PyRun_SimpleString("import numpy");
return 0;
}
From this code the output is:
Finally I also tried compiling original version of main.cpp code in release mode and then the output is:
So, my question here is: What can I do to get numpy working under debug compilations using an embedded interpreter on Visual Studio 2008?
You know you have to have use a python debug version built don't you? That is probably your problem. (I would leave a comment but no rep ): )

python code to c++ lib or dll

I have some python code that I want to use from C++, I want to build it in lib or dll? how can I do it?
code have dependencies:
import socket
import string
import struct
import sys
and maybe PIL
You can use cython and write thin wrapper to export it to C
Cython lib helloWorld.pyx:
import sys
sys.path.append(".") #yourlib is in current folder
import yourlib #you can import any python module
cdef public void helloWorld():
print "Hello World Cython!"
yourlib.helloWorld("Python")
cdef public int my_sum(int x, int y):
return x*x+y
from libcpp.string cimport string
cdef public string testString( string sx, string sy ):
x = int(sx.c_str())
y = int(sy.c_str())
ret= "%d*%d+%d=%d"%(x,x,y,my_sum(x,y))
cdef char* ret2= ret
return string( ret2 )
Compile with cython (create helloWorld.cpp, helloWorld.h):
cython --cplus helloWorld.pyx
Your code program.cpp:
#include <string>
#include <iostream>
#include "Python.h"
#include "helloWorld.h" // it's cpp header so remove __PYX_EXTERN_C (bug)
int main(int argc, char *argv[]) {
Py_Initialize(); //start python interpreter
inithelloWorld(); //run module helloWorld
helloWorld();
std::cout << testString("6","6") << std::endl; #it's fast!
Py_Finalize();
return 0;
}
Compile and run:
g++ program.cpp helloWorld.cpp -I/usr/include/python2.7/ -lpython2.7
./a.out
Hello World Cython!
Hello World Python!
6*6+6=42
Another way is to use boost::python
Your code program.cpp:
#include <string>
#include <iostream>
#include <boost/python.hpp>
int main(int argc, char *argv[]) {
Py_Initialize();
boost::python::object sys = boost::python::import("sys");
sys.attr("path").attr("append")(".");
boost::python::object main_module = boost::python::import("yourlib");
main_module.attr("helloWorld")("boost_python");
boost::python::object ret= main_module.attr( "my_sum" )( 10, 10 );
std::cout << boost::python::extract<char const*>(ret) << std::endl;
Py_Finalize();
return 0;
}
Compile and run:
g++ program.cpp -I/usr/include/python2.7/ -lpython2.7 -lpython_boost
./a.out
Hello World boost_python!
10*10+10=110
You might want to check how to embed python in another application (http://docs.python.org/extending/embedding.html).