pybind11: RuntimeError for passing Numpy Array - c++

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.

Related

How to return the cv::Mat Data when I extend C++ using the distutils

I want to use a Open CV code writing by C++ as a python library.
But I cant find the way return cv::Mat data when I use distutils for wrapping.
cv_convarter.cpp
#include <Python.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
static PyObject* cv_imread(PyObject *self, PyObject *args)
{
cv::Mat img;
img = cv::imread("sample.png", 1);
//if(img.empty()) return -1;
// Py_RETURN_NONE;
// How to return array or cv::Mat or numpy
//return img;
};
static PyMethodDef cv_convarter_methods[] = {
{
"cv_imread",
cv_imread, METH_NOARGS,
"output cv imread array."
},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef cv_convarter_definition = {
PyModuleDef_HEAD_INIT,
"cv_convarter",
"CV Convarter Sample.",
-1,
cv_convarter_methods
};
PyMODINIT_FUNC PyInit_cv_convarter(void){
Py_Initialize();
return PyModule_Create(&cv_convarter_definition);
}
setup.py
#!/usr/bin/env python3
# encoding: utf-8
from distutils.core import setup, Extension
cv_convarter_module = Extension(
'cv_convarter',
include_dirs=['/usr/include/python3.4'],
extra_compile_args=['-std=c++11'],
sources=['cv_convarter.cpp']
)
setup(
name='cv_converter',
version='0.1.0',
description='example opencv c++ convert python library',
ext_modules=[cv_convarter_module]
)
then,
python3 setup.py build
I can get
cv_convarter.cpython-34m.so
But I cant import this library and I get the error message.
ImportError: Pathofsofile/cv_convarter.cpython-34m.so:
undefined symbol: _ZN2cv3Mat10deallocateEv
How to write the extending code that return a cv::Mat data.

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.

How to print to Python terminal with Boost::Python

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!

turtlebot 2 kobuki base move forward

I want to move the turtlebot.package name is "forward" Firstly i created package inside my catkin_ws
$ catkin_create_pkg forward std_msgs rospy roscpp actionlib tf geometry_msgs move_base_msgs
Then i edit CMakeList
add_executable(gg src/g.cpp) and target_link_libraries(gg, ${catkin_LIBRARIES})
Thirdly, i run these commands:
catkin_make
roscore
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:'pwd'
source ./devel/setup.bash
rosrun forward gg.cpp
gg.cpp:
#include <ros/ros.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <geometry_msgs/Twist.h>
#include <tf/transform_datatypes.h>
#include <stdio.h>
#include <math.h>
#include <tf/transform_listener.h>
#include <algorithm>
#include <geometry_msgs/PointStamped.h>
#include <std_msgs/Header.h>
#include <iostream>
int main(){
geometry_msgs::PointStamped p;
geometry_msgs::PointStamped p1;
p.header.stamp = ros::Time();
std::string frame1 = "/camera_depth_optical_frame";
p.header.frame_id = frame1.c_str();
p.point.x = 0;
p.point.y = 0;
p.point.z = 1; // 1 meter
// std::string frame = "map";
/*try
{
listener.transformPoint(frame,p,p1);
}catch(tf::TransformException& ex) { ROS_ERROR("exception while transforming..."); }
*/
// create message for move_base_simple/goal
geometry_msgs::PoseStamped msg;
msg.header.stamp = ros::Time();
std::string frame = "/map";
msg.header.frame_id = frame.c_str();
msg.pose.position = p1.point;
msg.pose.orientation = tf::createQuaternionMsgFromYaw(0.0);
//publisher.publish(msg);
}
errors:
[rosrun] Couldn't find executable named gg.cpp below /home/turtlebot/catkin_ws/src/forward
[rosrun] Found the following, but they're either not files,
[rosrun] or not executable:
[rosrun] /home/turtlebot/catkin_ws/src/forward/src/gg.cpp
what do you think about these errors?
You name your executable gg:
add_executable(gg src/g.cpp) and target_link_libraries(gg, ${catkin_LIBRARIES})
But try to run the target gg.cpp
rosrun forward gg.cpp
try
rosrun forward gg

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).