create a boost::python::object from a noncopyable instance - boost-python

I was wondering if any one here might be able to help me out with the following problem I'm having.
I seem unable to create a boost::python::object from a c++ class I've bound to python that is noncopyable. Here is a simplified example..
#include <boost/python.hpp>
class A
{
public:
static A*
create() {return new A;}
protected:
A(){}
};
void
doSomething(const A& a)
{
boost::python::object obj(a);
}
BOOST_PYTHON_MODULE(test)
{
boost::python::class_<A, boost::noncopyable>("A", boost::python::no_init)
.def("__init__", boost::python::make_constructor(&A::create));
boost::python::def("doSomething", &doSomething);
}
Then at runtime in python
import test
a = test.A()
test.doSomething(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: No to_python (by-value) converter found for C++ type: A
I realise that the boost::noncopyable parameter prevents a to_python converter for A being registered. Does anyone know how I might be able to create a boost::python::object from an A instance ?
thanks in advance!

Use this
boost::python::object obj(**boost::cref(a)**);

Related

How to inherit from `LeafSystem<T>` in other pybind11 module

first of all, thanks for this great project!
I have the following situation: I'm developing a C++ library which uses drake as a dependency. Specifically I have a custom System, inheriting from LeafSystem<T>:
// my_system.h
#include <drake/systems/framework/leaf_system.h>
template <typename T>
class MySystem : public drake::systems::LeafSystem<T> {
public:
MySystem() {}
};
I want to expose this system also via a Python API, also using pybind11 like drake is doing, i.e.:
// my_module.cpp
#include "my_system.h"
#include <drake/systems/framework/leaf_system.h>
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(my_module, m) {
py::module::import("pydrake.systems.framework");
py::class_<MySystem<double>, drake::systems::LeafSystem<double>>(m, "MySystem").def(py::init<>());
}
This compiles with CMake, life is good. But when I try to import MySystem in python, the base class cannot be resolved:
>>> import my_module
Traceback (most recent call last):
Cell In [2], line 1
import my_module
ImportError: generic_type: type "MySystem" referenced unknown base type "drake::systems::LeafSystem<double>"
I suspect it has something to do with the way drake generates the actual name of the binding, but this is all way beyond my head:
https://github.com/RobotLocomotion/drake/blob/72794d7818ef51629ed97faf6cd325004f49eb9a/bindings/pydrake/common/cpp_template_pybind.h#L90-L93
How can I create python bindings for my class which inherits from drake::system::framework::LeafSystem (or any other system, really)?
Thanks for your help!
The only relevant information I could find on pybind11 is from the officle docs about inheritance, which don't apply in my case, since the bindings of the base have already been written.
I tried to simulate the situation by compiling a libfoo.so which exports one base class Foo and its bindings. If MySystem inherits from Foo I can get the python binding to work just fine:
// Simulated foo library and its bindings
class Foo {};
#include "foo.h"
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(foo, m) {
m.doc() = "hello, foo";
py::class_<Foo>(m, "Foo").def(py::init<>());
}
In another lib, this now works:
class MySystem : Foo {};
PYBIND11_MODULE(my_module, m) {
py::class_<MySystem, Foo>(m, "MySystem").def(py::init<>());
}
Does it fix it if you add py::module::import("pydrake.systems.framework"); to your PYBIND11_MODULE before trying to define your class?
For any C++ classes used by a pybind11 binding that are from other modules, you need to py::import that module before you can inherit from it (or use it as an argument, or etc).

When I try to handle the exception by using the custom exception class , do I need to use alias?

class InsufficientBalance(ZeroDivisionError):
def __init__(self,text):
self.text=text
balance=5000
try:
AmtToBeWithdrawn=int(input("Enter the amount you want to withdraw"))
if AmtToBeWithdrawn>balance:
raise InsufficientBalance("Bhosdike aukat me rahkar amount dal")
except InsufficientBalance as i:
print(i.text)
else:
balance=balance-AmtToBeWithdrawn
print("Withdrawal Successfull")
finally:
print("Remaining balance on the account",balance)
When we use the as keyword in the above code , does the as keyword create the object of the InsufficientBalance class? because if that does not create the object then , how is it possible to access the instance variable text? When I just write
except InsufficientBalance as i:
print(i.text)
it gives the exception
Traceback (most recent call last):
File "C:/Users/HP/Desktop/Fullstack dev SR/Python/ASS27.py", line 103, in <module>
print(InsufficientBalance.text)
AttributeError: type object 'InsufficientBalance' has no attribute 'text'
but when I write
except InsufficientBalance as i:
print(i.text)
the code does not produce any exception , why is it so?
Thanks in advance for replying.

Using a Function pointer inside a class crashes the compiler (but works inside a function)

Reference class
class commandsListClass
{
public:
std::string name;
std::string description;
std::vector<std::string> commands;
columnHeaders headersRequired;
void (*function)(System::Object ^ );
std::string recoveryFileHeader;
void reset()
{
name = "";
description = "";
commands.clear();
headersRequired.reset();
recoveryFileHeader = "";
function = dummyFunc; // dummyFunc uses the same members as the intended - this is to ensure it is defined. DummyFunc is empty, returns void etc
}
commandsListClass()
{
reset();
}
};
Currently, if I run the below code, the compiler crashes
// This crashes the compiler
System::Threading::ThreadPool::QueueUserWorkItem(gcnew System::Threading::WaitCallback(global::commandsList[index].function ), ti);
1>------ Build started: Project: MyProject, Configuration: Release x64 ------
1> project.cpp
1>c:\users\guy\documents\visual studio 2012\projects\MyProject\MyProject\Form1.h(807): fatal error C1001: An internal error has occurred in the compiler.
1> (compiler file 'msc1.cpp', line 1443)
1> To work around this problem, try simplifying or changing the program near the locations listed above.
1> Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
If I declare a member inside the same function as I am making the call, and set it to the global::commandsList[index].function, it compiles and runs correctly
// This runs correctly
void (*func)(System::Object ^);
func = global::commandsList[index].function;
System::Threading::ThreadPool::QueueUserWorkItem(gcnew System::Threading::WaitCallback(func ), ti);
global::commandsList is a vector of type commandsListClass
Any ideas? Browsing Google and SO suggest changing the compiler to not optimize, which I've tried with no success. The code is written in such a way that:
That point in the code cannot be reached if index does not point to a valid member of the global::commandsList vector
The function variable is guaranteed to be set, either to the dummyFunc on creation, or the correct (requested) function as set elsewhere in the code.
Any help would be greatly appreciated.
Edit 1: This is using Visual Studio 2012, Windows 7 x64
Here's a simplified repo:
public delegate void MyDel(Object^);
void g(Object^) {}
struct A {
static void(*fs)(Object^);
void(*f)(Object^);
gcroot<MyDel^> del;
};
void(*fg)(Object^);
void h()
{
void (*f)(Object^);
A a;
gcnew MyDel(f);
gcnew MyDel(fg);
gcnew MyDel(a.fs);
a.del = gcnew MyDel(g);
//gcnew MyDel(a.f); // this line fails
// work around
f = a.f;
gcnew MyDel(f);
}
Only the non-static member variable fails. Seems like a compiler bug. Work around it by using a local intermediate.
Or better is Lucas's suggestion to use gcroot.

Text widget is not accessible to a helper function in Python3x tkinter

I am learning python tkiner from a reference book. The examples are coded in plain style, i.e., not in class format. I want to learn coding in classes because I think it helps manage long codes.
I am trying to make the text widget (named textPad) accessible to a helper function inside a class called TextEditor. The job of the helper function is to select all the text which I type. However, as soon as I run the script, I get global error that the textPad is not defined. Even when I add self. to textPad, i.e., self.textPad, I get an attribute error that Class object has no attribute textPad. The code is part of an excercise to make a full functional text editor. Below, I provide the core code which generates the error. What is the wrong with this code?
Could you please clarify my doubts: where is the best place to define helper functions: inside class or outside class? In both cases, how to make them accessable?
from tkinter import *
class TextEditor():
def __init__(self, root):
self.select_all() #helper function declare
myMenu = Menu(root, tearoff=0) #Menu bar
editMenu = Menu(root, tearoff)
editMenu.add_command(label="Select All", accelerator="Ctrl+A", command=select_all)
myMenu.add_cascade(label="Edit", menu=editMenu)
root.config(menu=myMenu)
textPad = Text(root, wrap="word", undo=True)
textPad.pack(expand="yes", fill="both")
def select_all(self):
textPad.tag_add('sel', '1.0', 'end')
if __name__ == '__main__':
root=Tk()
app = TextEditor(root)
root.mainloop()
This is the error:
Traceback (most recent call last):
File "C:\Python33\gui\tkguibook\textpad.py", line 21, in <module>
app = TextEditor(root)
File "C:\Python33\gui\tkguibook\textpad.py", line 6, in __init__
self.select_all() #helper function declare
File "C:\Python33\gui\tkguibook\textpad.py", line 17, in select_all
textPad.tag_add('sel', '1.0', 'end')
NameError: global name 'textPad' is not defined
Thank you in advance for your kind help!
First of all, I advise you to watch some tutorials on object-oriented paradigm in Python without using tkinter directly.
The problem with your code is that textPad is not a property of the class, but it's a simple local variable to the __init__ method or constructor. To make it a property, you should use self to declare and then refer to the just declared property.
For example, suppose I have the following class:
class TextEditor:
def __init__(self):
# stuff
and you want to add a property, visible in all the points in your class, you can do it in this way:
class TextEditor:
def __init__(self):
self.textPad = tkinter.Text() # using 'self' to declare a property
now, if you want to refer to that property in another method, you should use always the self:
class TextEditor:
def __init__(self):
self.textPad = tkinter.Text()
def set_text(self, new_text):
self.textPad.insert(tkinter.END, "hello") # using 'self' to refer to the property
To know more about self.

Class in parameter of function (Arduino) does not compile

I am trying to create a simple class in C++, but I keep getting the compilation errors:
main:2: error: variable or field 'doSomething' declared void
main:2: error: 'person' was not declared in this scope
main:
class person {
public:
int a;
};
void doSomething(person joe) {
return;
}
main() and stuff would go here, but even if I include main(){}, the errors still occur. I also tried adding 2 closed parentheses after joe, but then that creates the error:
main: In function 'void doSomething(person (*)())':
main:8: error: request for member 'a' in 'joe', which is of non-class type 'person (*)()'
Any help is greatly appreciated. (I hope this isn't something really stupid I'm missing, because I've been researching for hours).
Edit: I found out this is an Arduino-specific error. This post answers it.
I found out after reading this post that a way to work around this is:
typedef struct person{
public:
int a;
};
void doSomething(void *ptr)
{
person *x;
joe = (person *)ptr;
joe->a = 3; //To set a to 3
//Everything else is normal, except changing any value of person uses "->" rather than "."
return;
}
main()
{
person larry;
doSomething(&larry);
}
So essentially it is:
-Change class to typedef struct
-in the parameter, replace newtype with void *something
-add person *x; and x = (person *)ptr; to the beginning of the function
-whenever accessing type property, use -> rather than .
I'm not a expert but when I try to do what you want to do, I do it this way:
//create an instance of my class
MyAwesomeClass myObject;
void myFunction(MyAwesomeClass& object){
//do what you want here using "object"
object.doSomething();
object.doSomethingElse();
}
void setup() {
//setup stuff here
myObject.init();
}
void loop() {
//call myFunction this way
myFunction(myObject);
}
As I said, I'm not a C++ expert but it does the job.
Hope it helps!
My guess is, you have an invalid syntax error somewhere in the declarations above "class person...". Can you copy and paste the whole file?