How do I return a reference to a dynamic type from C++ and hold it in Python? - c++

I'm writing some code that returns a column value from a row based on the column index. The row is updated from time to time in C++, and I'd like the python code to keep a reference to the column value. The following code reflects my current solution, in which I have to repeatedly fetch the column value.
struct Foo
{
PyObject * get(int pos)
{
// Position 0 is an integer value. Position 1 is a float value
if (pos == 0)
return Py_BuildValue ("i", m_int);
else
return Py_BuildValue ("f", m_float);
}
void set_int(int i)
{
m_int = i;
}
void set_float(float f)
{
m_float = f;
}
int m_int;
float m_float;
};
My bindings are simple:
class_<Foo> ("Foo")
.def("get", &Foo::get)
.def("set_int", &Foo::set_int)
.def("set_float", &Foo::set_float)
;
This works at the python level like this:
In [16]: foo = Foo()
In [17]: foo.set_int(1)
In [18]: foo.set_float(2.5)
In [19]: i = foo.get(0)
In [20]: f = foo.get(1)
In [21]: i
Out[21]: 1
In [22]: type(i)
Out[22]: int
In [23]: f
Out[23]: 2.5
In [24]: type(f)
Out[24]: float
So far, so good. However, when I modify foo, I'd like i and f to reflect the new values. Currently, they reflect the old values.
In [25]: foo.set_int(42)
In [26]: i
Out[26]: 1
How do I setup the C++ and binding code so that 'get' returns a reference to rather than a copy of the Foo member variables?

You need to wrap the integer values in an object class. Primitives are immutable in Python so when you return an int value it will never reference the original int, just a const copy. You could return a new struct of the form:
struct IntWrap {
int *value;
int get() { return *value; }
void set_int(int nval) { *value = nval; }
...
};
class_<IntWrap > ("IntWrap")
.def("get", &IntWrap::get)
.set("set_int", &IntWrap::set_int)
...
and make wrapper function bindings that treat the struct as a mutable integer in Python. This however, does violate the constness idiom of primitives in Python.
Here's a post on effectively inheriting from str or int, where you could make changes to the integer style object to use IntWrap instead (in case you want something that acts more like an int out of the box).

Related

Save and load function pointers to file

Consider the following code:
typedef float (*MathsOperation)(float _1, float _2);
struct Data
{
float x, y;
MathsOperation op;
};
Data data[100];
float Add(float _1, float _2){//add}
float Sub(float _1, float _2){//subtract}
float Mul(float _1, float _2){//multiply}
// other maths operations
for (int i = 0; i < 100; ++i)
{
// assign one of the maths operators above to data struct member op
// according to some condition (maybe some user input):
if(condition1) data[i].op = &Add;
if(condition2) data[i].op = &Sub;
if(condition3) data[i].op = &Mul;
// etc.
}
Now I'd like to somehow save the dataarray to a file and load it later (maybe in another program which doesn't know about the conditions that were used to assign the operators to each array element). Obviously, the pointers would be different every time I ran the application. So, my question is what is the best way to do this?
You can't store "functions" as data anyway, and as you say, storing pointers in external media doesn't work. So, what you have to do in this case is store an operator value, e.g.
enum Operator
{
Op_Add,
Op_Sub,
Op_Mul,
Op_Largest // For array size below.
};
And instead of:
if(condition1) data[i].op = &Add;
if(condition2) data[i].op = &Sub;
if(condition3) data[i].op = &Mul;
have:
if(condition1) data[i].op = Op_Add;
if(condition2) data[i].op = Op_Sub;
if(condition3) data[i].op = Op_Mul;
Since that is an integer type value, it can be stored in a file, and you can then do:
// Or `fin.read(reinterpret_cast<char*>(data), sizeof(data))
fin >> op >> x >> y;
if (op == Op_Add) ...
else if (op == Op_Sub) ...
Or have a function pointer array that you index with op... In other words:
typedef float (*MathsOperation)(float _1, float _2);
...
MathsOperation mathsOps[Op_Largest] = { &Add, &Sub, &Mul };
...
mathsOps[op](x, y);
...
If I where you I would build an index, where you could register your operators
static std::array<MathsOperation> MathsOperations;
MathsOperations.push_back(Add);
MathsOperations.push_back(Sub);
MathsOperations.push_back(Mul);
int getIdx(MathsOperation op) {
return std::find(MathsOperations.begin(), MathsOperations.end(), op) - MathsOperations.begin();
}
and put it in a .h file just after the MathsOperation definitions
Then rather then saving the function pointer, you could just save the relevant index and access the operator afterwards
int opidx = getIdx(Add);
MathsOperator op = MathsOperator[idx];
Non-portable, but almost certain to work if all your functions are in the same module:
template<typename FuncT>
intptr_t FunctionPointerToId( FuncT* fptr )
{
return reinterpret_cast<intptr_t>(fptr) - reinterpret_cast<intptr_t>(&Add);
}
template<typename FuncT>
FuncT* FunctionPointerFromId( intptr_t id )
{
return reinterpret_cast<FuncT*>(i + reinterpret_cast<intptr_t>(&Add));
}
This assumes that your implementation preserves relative addresses of functions within the same module (most platforms do guarantee this as implementation-specific behavior, since dynamic loaders rely on this). Using relative addresses (aka "based pointers") allows it to still work even if the module is a shared library that gets loaded at a different base address each time (e.g. ASLR).
Don't try this if your functions come from multiple modules, though.
If you have the ability to build and maintain a list of the functions, storing an index into that list is definitely a better approach (those indexes can remain good even after relinking, while relative code addresses get changed).
You need some permanent identifier for each function. You save this identifier instead of function address and restore address after reading.
The simpliest is the integer identifier which is an index of array
const MathsOperation Operations[] = { &Add, &Sub };
In this case you must never change the order of Operations items.
If it is impossible, use strings:
const std::map<std::string, MathsOperation> OpNames
{
{ "Add", &Add },
{ "Sub", &Sub },
};

c++ overload the [] operator for write/set

I have done numerous searches and found a ton of examples and tutorials but still cannot figure out how to get the value when writing to the [] operator...
I feel like i'm going insane. I must be missing something very simple
as far as i can tell there is a single function for get and set and it looks something like this:
V& operator[](string K);
or this:
double &operator[](int n);
now great, we can get what is:
a[HERE]
as HERE becomes double &operator[](int HERE);
and we can easily work with it
but how do we get what is:
a[4] = HERE
C# has two very clear get and set methods with the value keyword which represents the object being assigned.
public string this[int key]
{
get
{
if(key == 1)
return "1!";
if(key == 2)
return "2!";
else
return "3!";
}
set
{
if( value == "setting") //value is a[3] = THIS
this.isSet = true;
}
}
Don't think of operator[] as a function to get or set, that might be confusing. Think of it as a normal function. In fact, let's re-write it as a normal function:
struct X
{
int arr[10];
int& getIndex(int idx) { return arr[idx]; }
};
//...
//initialize x of type X
x.getIndex(3) = 42;
The method x.getIndex(3) will return a reference to the 4-th element in the member array idx. Because you return by reference, the return value is an l-value and refers to that exact element, so you can assign a value to it, say, 42. This will modify the member x.arr[3] as the function returns an alias for that particular object.
Now you can re-write this in terms of operator[] exactly as before
struct X
{
int arr[10];
int& operator[](int idx) { return arr[idx]; }
};
and get the same result by calling
x[3];
or even
x.operator[](3);
The operator option is just syntactic sugar.

c++: - setting default initializer_list argument Y of size argument X, where X and Y are function parameters

Consider the following code
enum class VAR_CHANGE{TYPE1, TYPE2, TYP3};
void cell ( const std::initializer_list<double>& values,
const std::initializer_list<VAR_CHANGE>& change_type = [[[ !!!!!]]] )
{
// do something
}
I want to replace the [[[ !!!!!]]] so that the default initializer list comes to
{VAR_CHANGE::TYPE1, VAR_CHANGE::TYPE1, ....}
of size
values.size()
I want to do this because usually, I want to pick enum type VAR_CHANGE::TYPE1 to all of the values in initializer list 'values'.
For example:
cell({1.2, 2.2, 6.7});
would actually be,
cell({1.2, 2.2, 6.7}, {VAR_CHANGE::TYPE1, VAR_CHANGE::TYPE1, VAR_CHANGE::TYPE1});
I can overload the function but wondering if there is a nice generic way to do it represented as one function instead of passing the size around to do this.
You can use this hack:
enum class VAR_CHANGE{TYPE1, TYPE2, TYP3};
void cell ( const std::initializer_list<double>& values,
const std::initializer_list<VAR_CHANGE>& change_type = {} )
{
if(values.size() > 0 && change_type.size()==0)
{
// default
}
// do something
}
int main()
{
cell({12.4, 234.4});
cell({12.4, 234.4}, {VAR_CHANGE::TYPE1, VAR_CHANGE::TYPE2});;
}
Or make it better!

exposing method with unsigned char & argument using Boost.Python

I've closed-source C++ library, which provides header files with code equivalent to:
class CSomething
{
public:
void getParams( unsigned char & u8OutParamOne,
unsigned char & u8OutParamTwo ) const;
private:
unsigned char u8OutParamOne_,
unsigned char u8OutParamTwo_,
};
I'm trying to expose that to Python, my wrapper code is something like this:
BOOST_PYTHON_MODULE(MySomething)
{
class_<CSomething>("CSomething", init<>())
.def("getParams", &CSomething::getParams,(args("one", "two")))
}
Now I'm trying to use that in Python, which fails horribly:
one, two = 0, 0
CSomething.getParams(one, two)
Which results in:
ArgumentError: Python argument types in
CSomething.getParams(CSomething, int, int)
did not match C++ signature:
getParams(CSomething {lvalue}, unsigned char {lvalue} one, unsigned char {lvalue} two)
What do I need to change either in the Boost.Python wrapper code or Python code to make it work? How do I add some Boost.Python magic to automatically cast PyInt to unsigned char and vice-versa?
Boost.Python is complaining about a missing lvalue parameter, a concept which does not exist in Python:
def f(x):
x = 1
y = 2
f(y)
print(y) # Prints 2
The x paramter of the f function is not a C++-like reference. In C++ the output is different:
void f(int &x) {
x = 1;
}
void main() {
int y = 2;
f(y);
cout << y << endl; // Prints 1.
}
You have a few choices here:
a) Wrap the CSomething.getParams function to return a tuple of the new parameters values:
one, two = 0, 0
one, two = CSomething.getParams(one, two)
print(one, two)
b) Wrap the CSomething.getParams function to accept a class instance as parameter:
class GPParameter:
def __init__(self, one, two):
self.one = one
self.two = two
p = GPParameter(0, 0)
CSomething.getParams(p)
print(p.one, p.two)

set a member attribute in a "generic" way

Is it possible to set a member attribute in a "generic" way?
I am still new to c++ and just dived into templates, if this is the way to go?
The class i have to use has around 20 string members to be filled from informix database and i could loop through an array with the field(=attribute) names.
Let's say i have a simple class
class Foo
{
public:
attr1
attr2
Foo() { };
~Foo();
}
and i could use it like that:
Foo foo;
string myattr = "attr1";
string myval = "val x1";
string myval = "val x2";
setattribute( foo, myattr, myval1 ); // pseudocode... possible somehow?
cout << foo.attr1; // prints "val x1"
setattribute( foo, myattr, myval2 ); // pseudocode... possible somehow?
cout << foo.attr1; // prints "val x2"
The method i call in the loop could look like this...
// its_ref : empty string reference
// row: ptr on the current db row = query result object
// colname: the db column = attribute
// ki: the object
void get_fd( ITString & its_ref, ITRow * row, ITString colname, ns4__SOAPKunde& ki ) {
ITConversions *c;
ITValue *v = row->Column( colname );
v->QueryInterface(ITConversionsIID, (void **) &c);
c->ConvertTo( its_ref );
// here is the place i want to use it :
setattribute( ki, colname, its_ref.Data() );
}
You can use member data pointers. These can be of any type- e.g.
struct x {
int y;
int z;
};
int main() {
int x::* res = &x::y;
}
However, if you want to start accessing them by identifier at runtime, you will have to build your own system from scratch.
The only option I can think of would be to store you attributes in a map of boost::any. With the assumption that you want your attributes to be of heterogeneous types.
The basic idea is to replace your attributes in Foo with map. So instead of having all your private attributes you would have a map that wraps them. The problem with C++ is that your attribute names don't exist after compiling the program (unlike other scripted languages like python). So there is no way to access an attribute variable from a string representing it's name without using some kind of data structure
removed old edit_
You could use a std::map.
The (base) class of 'ki' then has to implement setattribute like this:
// Member variable of MyClass
std::map<string, string> mProps;
void MyClass::setattribute( const char * name, const char * value )
{
mProps[name] = value;
}