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

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

Related

Cannot use make_constructor in boost::python when declaring external constructor

I'm trying to defined an external constructor when porting a class to python, by using make_constructor absolutely fails. When I try:
#include <boost/python/numpy.hpp>
using boost::python;
class foo
{
int i;
public:
foo(int i) : i(i){}
};
foo foo_create(int i){return foo(i);}
BOOST_PYTHON_MODULE(bar)
{
class_<foo>("foo")
.def("__init__", make_constructor(&foo_create));
}
I get the following error
error: no type named ‘element_type’ in ‘class foo’
I tried using noinit and init() with the same result. What am I doing wrong?
Awe found the problem, part of it being the really sparse documentation on make_construction. I needed to return a ptr to a new instance like so (in this case I made them shared pointers):
#include <boost/python/numpy.hpp>
#include <memory>
using boost::python;
class foo
{
int i;
public:
foo(int i) : i(i){}
};
std::shared_ptr<foo> foo_create(int i){return std::shared_ptr<foo>(foo(i));}
BOOST_PYTHON_MODULE(bar)
{
class_<foo, std::shared_ptr<foo>>("foo")
.def("__init__", make_constructor(&foo_create));
}
The documentation on make_constructor is really sparse, but there is some discussion here: https://wiki.python.org/moin/boost.python/HowTo under point "9".

unknown type name on defining object of another class from same file in C++

In my one c++ file named "two_elements.cpp", I am defining two classes within same file, and the code goes like below:
#include <iostream>
#include <cstream>
class A{
public:
void methodA(){
//do something
}
};
class B{
public:
A a_obj;
a_obj.methodA();
};
This throws the following error:
error: unknown type name 'a_obj'
I folowed the following stack overflow links comprehensively, but could not find a work around:
Unknown type name class
unknown type name 'class'
C++ - 2 classes 1 file
Please note most of these questions had classes in the individual header files.
I found the solution:
#include <iostream>
#include <cstream>
class A{
public:
void methodA(){
//do something
}
};
class B{
public:
A a_obj;
B(){
a_obj.methodA();
}
};
An instance needs to be called inside a constructor or a function in c++.

swig perl wrapper is not generating for class member functions

I have simple c++ class as below
//example.h
#include<iostream>
class example
{
public:
int member;
void display(){
std::cout<<"Hello from example class"<<std::endl;
}
};
//my example.i file is
%module example
%{
#include "example.h"
%}
%include "example.h"
after this I am running
pkgs/swig/2.0.8/bin/swig -c++ -perl5 example.i
but I don't see a wrapper defined for my display function in .pm module thus generated.
any working sample will be of great help.
Thanks,
Harish
even though I don't see a special wrapper for display method, I see something like below generated and it worked when i was trying to access it from perl
*display = *examplec::example_display;
my code to access the c++ class objects
use example;
$myObj =new example::example();
$myObj->{member} = 1000;
print $myObj->{member};
print "\n";
$myObj->display();
print "\nFinished";

TypeScript "use"/alias for Classes

Is there a way to do an alias or "use" (like PHP) for a TypeScript class/module.
Example:
If I have:
module Foo {
class Bar {}
}
Normally I have to write Foo.Bar to use it outside of the module. Is there a way I can alias that to something else, like "FooBar".
This would be really useful if you have several submodules (which my current project does), like:
module A.B.C.D {
export class E {}
}
is normally A.B.C.D.E which is silly.
According to page 82 of the old Typescript language spec, it stated that the following is possible.
So you should be able to alias "use" a module without having to reference the entire hierarchy.
module A.B.C
{
import XYZ = X.Y.Z;
export function ping(x: number) {
if (x > 0) XYZ.pong(x – 1);
}
}
module X.Y.Z
{
import ABC = A.B.C;
export function pong(x: number) {
if (x > 0) ABC.ping(x – 1);
}
}
The new Typescript language spec covers similar material in the section on Import Alias Declarations

Eclipse undefined reference

I'm using Eclipse and MinGW. I've got undefined reference to error to all that I write in h files, that I do include in cpp-file where main located. I create an empty project, and the same thing again (
main.cpp
#include <iostream>
#include "Stack.h"
using namespace std;
int main(){
Stack<int> stack(10);
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
return 0;
}
stack.h
#ifndef STACK_H_
#define STACK_H_
template <class T>
class Stack{
private:
struct StackEl;
StackEl *top;
public:
Stack();
Stack(T el);
~Stack();
void Push(const T& el);
T Pop();
};
#endif /* STACK_H_ */
and stack.cpp inplements everything from stack.h
If I include not h-file, but cpp - all works. Help please!
I've got following errors
D:/Workspacee/Stack2/Debug/../src/Stack2.cpp:16: undefined reference to `Stack<int>::Stack(int)'
D:/Workspacee/Stack2/Debug/../src/Stack2.cpp:18: undefined reference to `Stack<int>::~Stack()'
D:/Workspacee/Stack2/Debug/../src/Stack2.cpp:18: undefined reference to `Stack<int>::~Stack()'
This is a linker error. I'm no Eclipse expert, but you have to tell it somehow to add Stack.o to the linking command.
If you include Stack.cpp instead of Stack.h, the implementations from the cpp-file get included into main.cpp by the preprocessor before compilation, so the linking stage has no unresolved references to outside functions.
My bad, that is becouse templates! When you use template, all code, including realization of functions, must be in header-file, or you have to write prototypes for every type you are going to use you template-functions with. I've forgot about that working with templates is not the same as with usual function :(