Home | News | Documentation | Download

Call by reference, unsigned integer

can one call a ROOT/c++ function which has an unsigned integer as out parameter (call by reference) from pyroot?

Following does not work:

int test(unsigned int & a) { a = 3; }

[quote]

ROOT.gROOT.ProcessLine(".L test.c+")
a = ROOT.Long(7)
ROOT.test(a)
TypeError: int ::test(unsigned int& a) =>
could not convert argument 1[/quote]

only when the function uses a signed int this works.

Hi,

unless you use an old version of ROOT, the signed integer should not work either (what does work, for the signed case, is to pass a ROOT.Long()). At issue is that for that short-cut to work, the python object needs to have the same underlying representation as the C++ one. That is the case in p2.x on 32b for int (i.e. both are long, and same size).

In general, using an array from python module array of size 1 is the way to go, as that allows types to match:import array a = array.array('I',[0]) test(a)
Cheers,
Wim

1 Like

it works fine with ROOT.Long when the function takes a signed integer in 5.28.00a, only with unsigned integers it fails

In [27]: ROOT.gROOT.ProcessLine(".L test2.c+") Out[27]: 0L In [28]: cat test2.c int signedtest(int & a) { a = 3; } In [29]: a = ROOT.Long(7) In [30]: a Out[30]: 7 In [31]: ROOT.signedtest(a) Out[31]: 147421256 In [32]: a Out[32]: 3

using an array does not throw an exception but the result is wrong:

In [17]: cat test.c
int test(unsigned int & a)
{
  a = 3;
}
In [18]: a = array.array('I', [0])
In [19]: ROOT.test(a)
Out[19]: 162082244
In [20]: a
Out[20]: array('I', [0L])
In [21]: a[0]
Out[21]: 0L #WRONG

In [38]: ROOT.test(a[0])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/nfs/hicran/home/jtaylor/private/test/<ipython console> in <module>()

TypeError: int ::test(unsigned int& a) =>
    could not convert argument 1

Hi,

[quote=“MadCow”]it works fine with ROOT.Long when the function takes a signed integer in 5.28.00a, only with unsigned integers it fails[/quote]yes, that’s how it should be.

That looks like a bug … the pointer is passed by value (i.e. *a would do the trick). Same goes for passing of ctypes.c_uint.

Will have to think of a fix.

Later,
Wim

Hello Win,

I have the same question. Have you found a solution yet?

$ cat uchar.C 
void uchar(UChar_t& c)
{
  c = 10;
}
$ python
Python 2.6.5 (r265:79063, Jun 14 2010, 17:27:15) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ROOT
>>> ROOT.gROOT.ProcessLine(".L uchar.C+")
>>> import array
>>> c = array.array("B", [0])
>>> ROOT.uchar(c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: void ::uchar(UChar_t& c) =>
    could not convert argument 1 (expected string or Unicode object, array.array found)

I am using the SVN trunk and Python 2.6.5 on RHEL 5.5 (64 bit).

Hi,

no, sorry, haven’t yet: I’ve been spending the bulk of my python cycles on cppyy. I’ll have a look again when I’m back at the Lab (traveling tomorrow).

Cheers,
Wim

Hello Wim,

Thanks for clarifying the status. I get the similar error when I use pointer for the argument. Is this also the ROOT limitation?

[quote]

ROOT.uchar©
Traceback (most recent call last):
File “”, line 1, in
TypeError: void ::uchar(UChar_t* c) =>
could not convert argument 1 (expected string or Unicode object, array.array found)
[quoate][/quote]

Hi,

not a ROOT limitation as such, simply the choice in the interface that char*'s of any kind expect strings.

Cheers,
Wim

Hello Wim,

Is there any trick to assign an integer to UChar_t* in PyROOT?

Hi,

what does it mean to “assign an integer to UChar_t*”?

Cheers,
Wim

Hello Wim,

I mean, is it possible to use this function properly from PyROOT?

void uchar(UChar_t* c) { *c = 10; }

Hi,

no, since the non-const char converter (which is a special case) is only there for signed char; not for unsigned char. Of course, if you work with trunk, then you can pass it now since a few minutes (you’ll need a python array of type ‘B’, which according to the array module doc takes a python int anyway, since a python char (string of length one) consists of signed chars and would not fit all values).

Cheers,
Wim