Accessing variable in C++ that has been wrapped in Python - boost-python

How do I access a variable in C++ that has been wrapped in Python via BoostPython method like below(in this case I want to access y):
boost::python::exec("y = x", main_namespace);
Thanks in advance.
EDIT:
Assume y is an integer.

All Python classes, functions, variables, etc. are contained in dicts. Since you seem to already have the main_namespace dict, you can just do this:
using namespace boost::python;
// .................................................
object y = main_namespace["y"];
std::string yString = extract<char const*>(y);

Related

Python C API - How to inherit from your own python class?

The newtypes tutorial shows you how to inherit from a base python class. Can you inherit from your own python class? Something like this?
PyObject *mod = PyImport_AddModule("foomod");
PyObject *o = PyObject_GetAttrString(mod, "BaseClass");
PyTypeObject *t = o->ob_type;
FooType.tp_base = t;
if (PyType_Ready(&FooType ) < 0) return NULL;
though you need to define your struct with the base class as the first member per the documentation so it sounds like this is not possible? ie how would I setup the Foo struct?
typedef struct {
PyListObject list;
int state;
} SubListObject;
What I'm really trying to do is subclass _UnixSelectorEventLoop and it seems like my only solution is to define a python class that derives from my C class and from _UnixSelectorEventLoop with my C class listed first so that it can override methods in the other base class.
I think you're basically right on your assessment:
it seems like my only solution is to define a python class that derives from my C class and from _UnixSelectorEventLoop with my C class listed first so that it can override methods in the other base class.
You can't define a class that inherits from a Python class because it'd need to start with a C struct of basically arbitrary size.
There's a couple of other options that you might like to consider:
You could create a class the manual way by calling PyType_Type. See this useful answer on a question about multiple inheritance which is another sort of inheritance that the C API struggles with. This probably limits you too much, since you can't have C attributes, but you can have C functions.
You could do "inheritance by composition" - i.e. have you _UnixSelectorEventLoop as part of the object, then forward __getattr__ and __setattr__ to it in the event of unknown attributes. It's probably easier to see what I mean with Python code (which is simply but tediously transformed into C API code)
class YourClass:
def __init__(self,...):
self.state = 0
self._usel = _UnixSelectorEventLoop()
def __getattr__(self, name):
return getattr(self._usel, 'name')
def __setattr__(self, name, value):
if name in self.__dict__:
object.__setattr__(self, name, value)
else:
setattr(self._usel, name, value)
# maybe __hasattr__ and __delattr__ too?
I'm hoping to avoid having to write this C API code myself, but the slots are tp_getattro and tp_setattro. Note that __getattr__ will need to be more comprehensive in the C version, since it acts closer to the __getattribute__ in Python. The flipside is that isinstance and issubclass will fail, which may or may not be an issue for you.

Python Garbage Collection causes SegFault when destructing a C++ object

I have an in-house C++ library that I've successfully exposed to Python using Boost.Python. It accepts a user-created Python object and then uses some methods within that object to perform certain tasks, and it works quite well for the most part.
The Python use of the library looks like:
class Foo(object):
def __init__(self, args):
"""create an instance of this class with instance-specific attributes"""
def Bar1(self, a, b, c):
"""do something with the given integers a, b and c"""
return a + (b*c)
def Bar2(self, a, b, c):
"""do something else with the given integers a, b and c"""
print (a*b) + c
import mylib
cheese = mylib.Wine()
qux = Foo()
cheese.setup(qux)
cheese.do_something(1)
cheese.do_something(2)
The "Wine" object in C++ looks like:
#include <boost/python.h>
#include <Python.h>
class Wine {
public:
Wine() {};
~Wine() {};
void setup(boost::python::object baz) {
baz_ = baz;
};
static void do_something(boost::python::object pyreq) {
int request = boost::python::extract<int>(pyreq);
int a = 1;
int b = 2;
int c = 3;
if (request == 1) {
int d = boost::python::extract<int>(baz_.attr("Bar1")(a, b, c));
};
else if (request == 2) {
baz_.attr("Bar2")(a, b, c);
};
};
private:
static boost::python::object baz_;
};
BOOST_PYTHON_MODULE(mylib)
{
using namespace boost::python;
class_<Wine>("Wine")
.def("do_something", &Wine::do_something)
.staticmethod("do_something")
.def("setup", &Wine::setup)
;
};
The problem is that, after successfully executing all of the tasks, the program terminates with a SegFault. This isn't really a huge deal because the code that I need to execute still executes, and the tasks that I need to perform are all performed. The SegFault only occurs on the destruction of this C++ "Wine" object. Still, it's an inelegant outcome and I'd like to fix the problem.
What I could gather from an online search implied that this is a problem with improper declaration of ownership to Python. The end result is that the C++ destructor gets called twice, and the second call causes a SegFault.
Unfortunately I haven't been able to remedy the problem so far. Available documentation only covers the basics and I haven't been able to replicate some success others have had using boost smart pointers and some fancy declaration/destruction tricks in C++ with it. Any guidance would be much appreciated.
The problem is that the static Wine::baz_ object is being destroyed during static/global destruction. This is after the Python runtime has been finalized, but since boost::python::object uses the Python C-API, its destruction requires a valid Python runtime (though possible not if the object refers to None.) By arranging for baz_ to be destroyed before Python finalization, you should be able to avoid the segfault. The cleanest approach overall might be to make baz_ a non-static member variable.

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.

What does "->" mean in objective-c ? [duplicate]

I've seen this operator pop up quite a few times in example code in "Learn Objective C on the Mac."
I believe it's an operator in the C language which Objective C inherits.
I tried Googling and searching Stack Overflow and oddly nothing came up.
Does it have an English name?
It has to do with structures.
When we have a struct available locally on the stack, we access its members with the . operator. For example:
CGPoint p = CGPointMake(42,42);
NSLog(#"%f", p.x);
However, if we instead have a pointer to a structure, we have to use the -> operator:
CGPoint *p = malloc(1*sizeof(CGPoint));
p->x = 42.0f;
NSLog(#"%f", p->x);
free(p);
-> is not specific to Objective-C. It's a C operator.
Now that's cleared, it's the member access operator, equivalent to a pointer dereference and then using the dot operator on the result.
Say you had a struct like this:
typedef struct Person {
char *name;
} Person;
Person *jacob = malloc(1*sizeof(Person));
So this statement:
jacob->name = "Jacob";
Is equivalent to this statement:
(*jacob).name = "Jacob";
Of course, don't forget the free:
free(jacob);
In C
a->b
is a shortcut for
(*a).b
which is for dereferencing of members of a struct that is pointed to.
This is useful, because of . binds stronger than the dereferencing operator * . So by using -> you avoid having to use these ugly parentheses.
It's a member selection (or access) equivalent to a pointer de-reference (as pointed out in comments)
a->member is equivalent to (*a).member in C/C++
The same thing that it means in C. It can be used to access the instance variables of objects directly, but generally this is not the best practice. The dot notation you're referring to is a property, not the usual C dot notation.
It's the "indirect member access operator". It's a C operator, which both Objective-C and C++ inherited.
This
a->b
is equivalent to:
(*a).b
but is less typing. (The parens are necessary in the expanded form due to precedence of * and ..)
a->b is equivalent to (*a).b, and designates member b of the object pointed to by a.
In the C standard, it is called the "structure/union pointer operator," which isn't really the catchiest name.
It's all been said, it is a shortcut for accessing members of a struct pointer, but just a note to add that you can access ivars using the same syntax due to the way the Objective-C runtime works:
#interface Foo : NSObject {
NSString *something;
}
/* ... SNIP ... */
NSLog(#"something = %#", foo->something); // Where foo is an instance of the Foo class
This is handy when you need to access ivars that aren't exposed by methods; specifically when you need to implement copyWithZone: on your objects.

How can I specify the value of a named argument in boost.python?

i want to embed a function written in python into c++ code.
My python code is:test.py
def func(x=None, y=None, z=None):
print x,y,z
My c++ code is:
module = import("test");
namespace = module.attr("__dict__");
//then i want to know how to pass value 'y' only.
module.attr("func")("y=1") // is that right?
I'm not sure Boost.Python implements the ** dereference operator as claimed, but you can still use the Python C-API to execute the method you are intested on, as described here.
Here is a prototype of the solution:
//I'm starting from where you should change
boost::python::object callable = module.attr("func");
//Build your keyword argument dictionary using boost.python
boost::python::dict kw;
kw["x"] = 1;
kw["y"] = 3.14;
kw["z"] = "hello, world!";
//Note: This will return a **new** reference
PyObject* c_retval = PyObject_Call(callable.ptr(), NULL, kw.ptr());
//Converts a new (C) reference to a formal boost::python::object
boost::python::object retval(boost::python::handle<>(c_retval));
After you have converted the return value from PyObject_Call to a formal boost::python::object, you can either return it from your function or you can just forget it and the new reference returned by PyObject_Call will be auto-deleted.
For more information about wrapping PyObject* as boost::python::object, have a look at the Boost.Python tutorial. More precisely, at this link, end of the page.
a theoretical answer (no time to try myself :-| ):
boost::python::dict kw;
kw["y"]=1;
module.attr("func")(**kw);