swig perl wrapper is not generating for class member functions - perl

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";

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

Inline::java STUDY configuration

The Inline docs aren't too helpful in learning how to use the STUDY config,
can anyone clarify the syntax involved in calling a simple void method that prints a method, say, Hello() ?
Also, in terms of the external java file, is there a specific directory i need to put it in, or does it go in the same directory of the perl script?
Let's start with the file /home/foo/java_src/Hello.java, which contains:
public class Hello {
public Hello() {}
public void instance_hello() { System.out.println("hello world"); }
public static void static_hello() { System.out.println("HELLO WORLD"); }
}
Tackling your second question first, the first argument after use Inline Java ... can be a filename, and so you can put your source file anywhere and refer to it by its file name in your perl code:
use Inline Java => '/home/foo/java_src/Hello.java';
$obj = Hello->new();
$obj->instance_hello(); # "hello world"
Hello->static_hello(); # "HELLO WORLD"
Note that you don't need STUDY so far. The Hello class is defined in source code that is read directly by the Inline::Java module, so the module automatically creates and populates the Hello namespace in Perl.
STUDY is for classes that aren't parsed directly by Inline::Java. So let's say instead that our Hello class has been compiled into a jar file called /home/foo/jars/hello.jar. Now to use the Hello class you would need to (1) include hello.jar in your CLASSPATH and (2) use STUDY to tell Inline::Java to create the Hello namespace:
use Inline Java => 'STUDY',
CLASSPATH => '/home/foo/jars/hello.jar',
STUDY => ['Hello'];
$obj = Hello->new;
Hello->static_hello; # "HELLO WORLD"
$obj->instance_hello; # "hello world"
We include the first argument STUDY to signal to the Inline::Java that we're not passing any source code directly to the module. We could have also passed valid source code or a valid source code filename.
use Inline Java => 'public class Nothing() { }',
CLASSPATH => '/home/foo/jars/hello.jar',
STUDY => ['Hello'];

How can I import other files in Vala?

The question pretty much says it all- how could I import file2.vala to file1.vala?
You don't do it directly. If you run valac file1.vala file2.vala, it is as if you compiled them in one big file.
If you want to make them reusable, then you probably want a shared library. In which case, you compile one to produce a C header file and a VAPI definition:
valac --vapi file1.vapi -H file1.h --library libfile1.so file1.vala
The second one can then consume this:
valac --pkg file1 file2.vala
This assume that the VAPI file has been installed. If this is not the case, you'll need to pass --vapidir and the location where file1.vapi exists, probably .. Similarly, you'll need to inform the C compiler about where file1.h lives with -X -I/directory/containing, again, probably -X -I.. Finally, you'll need to tell the C linker where libfile1.so is via -X -L/directory/containing -X -lfile1. This is a little platform specific, and you can smooth the difference out using AutoMake, though this is a bit more involved. Ragel is the usual go-to project for how to use AutoMake with Vala.
just to supply apmasell:
you can use multiple files by using classes and public variables:
main.vala:
extern void cfunction(string text);
void main ()
{
first f = new first ();
f.say_something(f.mytext);
cfunction("c text\n");
}
class.vala:
public class first {
public string mytext = "yolo\n";
public first ()
{
stdout.printf("text from constructer in first\n");
}
public void say_something(string text)
{
stdout.printf("%s\n", text);
}
}
text.c:
#include <stdio.h>
void cfunction(const char *s)
{
puts("This is C code");
printf("%s\n", s);
}
compiles with: valac class.vala main.vala text.c
as you can see, you can even use C code

How to dynamically add a key:value property to c++ class, then make it accessible as class.property

In Python I have a flag class that I have found very useful. I'm newbe to c++, and can not seem to replicate this python functionality in c++. Rather than put up c++ code that didn't work, here's what I am looking to replicate, and I need some suggestions on where to go, templates, virtual, or ??
The requirement is being able to dynamically alter the members of the class, in python it's modifying the dict element of the class it's self that enables this.
In python:
import sys
args = []
... loads up args[] with keys:values looping through sys.argv[] ... blah blah blah
class Flag:
def __ init __(self, **args):
self. __ dict __.update(args)
now we enable flag.dynamicproperty
flag = Flag(**dict(args))
An example of use:
$ python script.py somedesc1 someval1 somedesc2 someval2
What this does is enables me to pass in parameters, as above, from the command-line and assign any number of them on-the-fly, and make then accessible by a flag.property (eg flag.somedesc1) call which returns somval1. Another way to maybe think about this is dynamically adding a key:value property to a C++ class.
An example of use in python code :
if flag.somedesc1 != '10': print someval1
I can't seem to make a comparable c++ work. I've looked into polymorphism, but these have to be assigned dynamically and then be accessible as a property of the class.
Ideas??? Surely c++ can do this, I'm just not sure where to start.
Okay, here is the solution I worked out; haven't tested it yet, but should work close enough to fit my needs using this format
flag.find(filename)
enum { filename, workers, runtime };
class flag {
vector<string> helplist;
public:
int add(int argc, char *argv[], string flag, string value, string description) {
string flagvalue;
flagvalue = value;
helplist.push_back(description);
for (int i; i < argv.length(); i++) {
if (argv[i]==flag) {
flagvalue = argv[i+1];
}
}
}
void showhelp() {
for (int i; i < helplist.length(); i++) {
cout << helplist[i] << endl;
}
}
};
No, you can't do this in C++. In C++, the members of a class are defined 100% at compile time. You cannot add any at runtime. The way to do this in C++ would be to have a member variable that's a map<string,string> that holds the key/value pairs, and then have a function string getVariable(string) that returns the value in the dictionary for that key.

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 :(