How can I specify the value of a named argument in boost.python? - 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);

Related

Null item error when placing factory registration within a function

I'm trying to write a function that creates registers an item with the factory then does some basic operations to that item. The problem I'm having is that when I try to execute this code, I get a null item error.
An example excerpt of the code I'd like to have would be:
modified_sequence_item example_msg_item
function new (string name = ex_sequence);
super.new(name);
create_message(example_msg_item, "example_msg_item", 32'hDEADBEEF);
endfunction
function create_message(modified_sequence_item msg_item, string msg_name, bit[31:0] data);
msg_item = modified_sequence_item::type_id::create(msg_name);
msg_item.data_field = data;
endfunction
Unfortunately, this doesn't work. I get the following error:
UVM_FATAL # 5710: reporter [NullITM] attempting to start a null item from sequence 'main'
However, the following code does work:
modified_sequence_item example_msg_item
function new (string name = ex_sequence);
super.new(name);
example_msg_item = modified_sequence_item::type_id_create("example_msg_item");
example_msg_item.data_field = 32'hDEADBEEF;
endfunction
Looking at these two bits of code, to me they are nearly identical aside from the actions being nested inside a function in the first bit of code. This leads me to believe the issue is most likely an issue with passing data being the functions.
Does anyone have any recommendations on how I could modify the first code example so that it does not have a null item error?
Two problems with your function declaration:
The handle that you are creating inside your function needs to be copied out when exiting the function, so msg_item needs to be declared as an output argument.
You forgot to declare the return type as void. Otherwise the default is a 1-bit 4-state result (IEEE Std 1800-2017, section 13.4 Functions: implicit_data_type)
function void create_message(
output modified_sequence_item msg_item,
input string msg_name, bit[31:0] data);
msg_item = modified_sequence_item::type_id::create(msg_name);
msg_item.data_field = data;
endfunction

How to assign method output to variable by reference MQL4

I'm guessing this question is going to apply to many similar languages other than MQL4 such as c++ (which I also forget how to use) which require you manually specify when you are passing by reference.
Method reference:
int[] previous = GetPrevious(i, ZigZagBuffer);
Method definition:
int GetPrevious[](int current, const double& buffer[])
{
int count = 0;
int result[];
// calculate count
ArrayResize(result,count);
// fill array
return result;
}
The resulting compile error is:
"Invalid Array Access"
From what I understand, this is because array's can only be passed by reference, but you have to explicitly state that you are passing it by reference. But the more I look up the syntax for passing by reference, the more I find articles about passing parameter by reference. (which I already know how to do as you can see in the code example.)
What is the syntax to assign the output of a method to a variable?
In case it matters, I only need to read the array multiple times; I'm not needing to alter or re-assign it after it is declared.
You cannot return array. You have to create it and pass into the function, fill inside the function and that's it.
OnTick(){
double array[]; //declaration of the array
fillArray(array,10); //passing array by ref, updating it there
Print(array[0]=0 && array[9]=9);//returns true
}
void fillArray(double &array[],int size){
ArrayResize(array,size);
for(int i=0;i<size;i++){array[i]=i;}
}

perl pass object method reference as parameter to function

i'm trying to do something like this:
-- source file 1
my $queue = Thread::Queue->new();
MyModules::populateQueue(<pass $queue->enqueue method reference);
...
-- package file
package MyModules
sub populateQueue {
my $enqueue = $_[0];
my $item = <find item to add to queue>;
$enqueue->($item);
...
first, i'm not able to add "bless" to Thread::Queue
i've tried a couple of suggestions i found in stackoverflow:
my $enqueueRef = $queue->can('enqueue');
MyModules::populateQueue(\&enqueueRef); <--- fails in the package at line
$enqueue->($item) with undefined subroutine
MyModules::populateQueue(\&queue->enqueue) <-- same failure as above
any idea how to pass a method of an object as a parameter to a function that can then be used in the function?
Perl doesn't have a concept of a bound method reference. my $enqueue = $object->can('method') will return a code ref to a method if it exists, but the code ref isn't bound to that particular object – you still need to pass it as the first argument ($queue->$enqueue($item) or $enqueue->($queue, $item)).
To pass a bound method, the correct solution is to use an anonymous sub that wraps the method call:
populate_queue(sub { $queue->enqueue(#_) });

Function pointer to member method in Matlab [duplicate]

I'm trying to grab a method handle from within an object in MATLAB, yet something in the sort of str2func('obj.MethodName') is not working
The answer is to get a function handle as #Pablo has shown.
Note that your class should be derived from the handle class for this to work correctly (so that the object is passed by reference).
Consider the following example:
Hello.m
classdef hello < handle
properties
name = '';
end
methods
function this = hello()
this.name = 'world';
end
function say(this)
fprintf('Hello %s!\n', this.name);
end
end
end
Now we get a handle to the member function, and use it:
obj = hello(); %# create object
f = #obj.say; %# get handle to function
obj.name = 'there'; %# change object state
obj.say()
f()
The output:
Hello there!
Hello there!
However if we define it as a Value Class instead (change first line to classdef hello), the output would be different:
Hello there!
Hello world!
One could also write
fstr = 'say';
obj.(fstr)();
This has the advantage that it does not require a handle class to work if the object (obj) is modified.
Use #. The following code works for me:
f = #obj.MethodName
No other answer mimics str2func('obj.MethodName'). Actually, this one doesn't either, not exactly. But you can define an auxillary function like so:
function handle = method_handle(obj, mstr)
handle = #(varargin) obj.(mstr)(varargin{:});
end
Then method_handle(obj, 'MethodName') returns a handle to obj.MethodName. Unfortunately, you cannot pass the variable name of obj as a string - eval("obj") will be undefined in the function's scope.

Accessing variable in C++ that has been wrapped in 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);