extracting null pointer address from PyCObject with ctypes

G

Gordon Allott

Hello :)

The result of various incompatibilities has left me needing to somehow
extract the address that a null pointer is pointing to with the null
pointer being exposed to python via PyCObject_FromVoidPtr

the code that creates the PyCObject is as follows:
tmp = PyCObject_FromVoidPtr (info.info.x11.display, NULL);
PyDict_SetItemString (dict, "display", tmp);
Py_DECREF (tmp);

which is exposed to python via a dictionary (the 'display' key). python
identifies that its a PyCObject but doesn't give any way to expose the
functionality. Essentially I am after the address that the void pointer
'info.info.x11.display' points to (as a long type)

As far as I can tell ctypes will only expose the pyObject type to me and
not actually let me deal with the data I am after, but being rather new
to ctypes I'm not sure weather this is correct.

--
Gord Allott ([email protected])


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFI7y2SlVw7T9GIvRsRArcbAKCjmewtdkEiahPXTHhhCUMy9D7NEgCfYTIQ
dE7a69MTHmR/3WUUSCzoSmc=
=Outo
-----END PGP SIGNATURE-----
 
A

Aaron \Castironpi\ Brady

Hello :)

The result of various incompatibilities has left me needing to somehow
extract the address that a null pointer is pointing to with the null
pointer being exposed to python via PyCObject_FromVoidPtr

the code that creates the PyCObject is as follows:
    tmp = PyCObject_FromVoidPtr (info.info.x11.display, NULL);
    PyDict_SetItemString (dict, "display", tmp);
    Py_DECREF (tmp);

Did you try:

tmp= PyLong_FromLong( ( long ) info.info.x11.display );
PyDict_SetItemString (dict, "display", tmp);
Py_DECREF (tmp);

Or also try:

PyCObject_AsVoidPtr( tmp );
 
G

Gordon Allott

Aaron said:
Did you try:

tmp= PyLong_FromLong( ( long ) info.info.x11.display );
PyDict_SetItemString (dict, "display", tmp);
Py_DECREF (tmp);

Or also try:

PyCObject_AsVoidPtr( tmp );

the problem is that I can't edit the C code - well I can and might
submit a patch to the project but I also need a solution that works from
the python side of things.


--
Gord Allott ([email protected])


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFI74sQlVw7T9GIvRsRAtw+AJ4i0lte6DnzeJ6Nm+BbaYGUCDDEIQCeIW4m
rlzxbYBLYI4j3hFceifTuLM=
=nfIm
-----END PGP SIGNATURE-----
 
A

Aaron \Castironpi\ Brady

the problem is that I can't edit the C code - well I can and might
submit a patch to the project but I also need a solution that works from
the python side of things.

I see. If I understand, you have a PyCObject in a dictionary.

Look at the 'ctypes' module and try calling PyCObject_AsVoidPtr. Its
return type should be 'c_void_p', and you can use 'result.value' to
get the original pointer.
 
G

Gordon Allott

Aaron said:
I see. If I understand, you have a PyCObject in a dictionary.

Look at the 'ctypes' module and try calling PyCObject_AsVoidPtr. Its
return type should be 'c_void_p', and you can use 'result.value' to
get the original pointer.

I have a hard time following that, if using ctypes you used PyDLL to
call PyCObject_AsVoidPtr on the PyCObject I already have surely it would
give me back a pointer (void for sake of simplicity) but it would be a
pointer to a new PyCObject and thus calling result.value on it would
only return the memory address of the new PyCObject?
--
Gord Allott ([email protected])


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFI78YSlVw7T9GIvRsRAm3eAJ0c9k7HFhXbEcq3O3jGYlMsziKIHACfS09u
5QTYKVR/SH6fPqToXhK9WVA=
=uL6v
-----END PGP SIGNATURE-----
 
A

Aaron \Castironpi\ Brady

I have a hard time following that, if using ctypes you used PyDLL to
call PyCObject_AsVoidPtr on the PyCObject I already have surely it would
 give me back a pointer (void for sake of simplicity) but it would be a
pointer to a new PyCObject and thus calling result.value on it would
only return the memory address of the new PyCObject?
--
Gord Allott ([email protected])

 signature.asc
< 1KViewDownload


Yes, well said. But no, not true, not necessarily. You can choose/
change return types with your code. If the call is defined already
and you can't change the return, just define a new one that returns
long.
 
G

Gordon Allott

Aaron said:
Yes, well said. But no, not true, not necessarily. You can choose/
change return types with your code. If the call is defined already
and you can't change the return, just define a new one that returns
long.

the problem is that the pointer or long or whatever it is thats returned
won't be the data I am after. the code for PyCObject_FromVoidPtr is as
follows:

PyObject *
PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
{
PyCObject *self;

self = PyObject_NEW(PyCObject, &PyCObject_Type);
if (self == NULL)
return NULL;
self->cobject=cobj;
self->destructor=destr;
self->desc=NULL;

return (PyObject *)self;
}


it obviously creates a new PyObject and returns that, which has already
happened once (the address I am after is passed to python via
PyCObject_FromVoidPtr(adress_i_am_after, NULL), doing that puts the
address I am after into the .cobject attribute of a new pyobject
structure and passes that to the python script via the 'display' key in
a dictionary.

If I were to then take the pycobject in this display key and pass it via
ctypes into PyCObject_FromVoidPtr it would simply create a new pycobject
and put a pointer to the old pycobject in the new pycobject's .cobject
attribute. it just means that I am getting further and further away from
where I want to be surely? if I were to take the current pointer at this
stage, to get to the address I actually want in C it would have to
follow something along the lines of
long address_i_want = (long)(new_pycobj->cobject->cobject);

What would be great is if there is some easy simple way of accessing the
.cobject attribute of the first pycobject thats passed via the
dictionary to python.

--
Gord Allott ([email protected])


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFI7/p9lVw7T9GIvRsRAr2rAJ9gxOUnLb8olXN6siH88ZLMwv2erwCfWD1q
+Y5jmOl0PrUzLTvmc3nMK/U=
=rL5l
-----END PGP SIGNATURE-----
 
A

Aaron \Castironpi\ Brady

the problem is that the pointer or long or whatever it is thats returned
won't be the data I am after. the code for PyCObject_FromVoidPtr is as
follows:

PyObject *
PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
{
    PyCObject *self;

    self = PyObject_NEW(PyCObject, &PyCObject_Type);
    if (self == NULL)
        return NULL;
    self->cobject=cobj;
    self->destructor=destr;
    self->desc=NULL;

    return (PyObject *)self;

}

it obviously creates a new PyObject and returns that, which has already
happened once (the address I am after is passed to python via
PyCObject_FromVoidPtr(adress_i_am_after, NULL), doing that puts the
address I am after into the .cobject attribute of a new pyobject
structure and passes that to the python script via the 'display' key in
a dictionary.

If I were to then take the pycobject in this display key and pass it via
ctypes into PyCObject_FromVoidPtr it would simply create a new pycobject
 and put a pointer to the old pycobject in the new pycobject's .cobject
attribute. it just means that I am getting further and further away from
where I want to be surely? if I were to take the current pointer at this
stage, to get to the address I actually want in C it would have to
follow something along the lines of
long address_i_want = (long)(new_pycobj->cobject->cobject);

What would be great is if there is some easy simple way of accessing the
.cobject attribute of the first pycobject thats passed via the
dictionary to python.

--
Gord Allott ([email protected])

 signature.asc
< 1KViewDownload

You are hard to follow. There is the 'cast' function, which I've had
some success with, even in adding pointers and offsets. It took a
look at the code for it though, and calling an undocumented version of
it. I can post that later if you don't have luck the same. You can
write extension modules to do that as well, and there's always a
Google search which personally I forget half the time too. Last, you
haven't mentioned an attempt with PyCObject_AsVoidPtr yet:

void* PyCObject_AsVoidPtr(PyObject* self)
Return the object void * that the PyCObject self was created with.

Where does that get you?
 
G

Gordon Allott

Aaron said:
You are hard to follow. There is the 'cast' function, which I've had
some success with, even in adding pointers and offsets. It took a
look at the code for it though, and calling an undocumented version of
it. I can post that later if you don't have luck the same. You can
write extension modules to do that as well, and there's always a
Google search which personally I forget half the time too. Last, you
haven't mentioned an attempt with PyCObject_AsVoidPtr yet:

void* PyCObject_AsVoidPtr(PyObject* self)
Return the object void * that the PyCObject self was created with.

Where does that get you?

sorry yes you were right, I was reading PyCObject_AsVoidPtr as
PyCObject_FromVoidPtr :)

using AsVoidPtr is a little confusing, this is the code I am using:
display = pygame.display.get_wm_info()['display']
pyobj = py_object(display)
ref = pointer(pyobj)

print pythonapi.PyCObject_AsVoidPtr(ref)

it produces the following traceback:
Traceback (most recent call last):
File "pygametest.py", line 125, in <module>
app = PyGameOGREApp()
File "pygametest.py", line 33, in __init__
self._createWindow(width, height, fullscreen)
File "pygametest.py", line 64, in _createWindow
print pythonapi.PyCObject_AsVoidPtr(ref)
TypeError: PyCObject_AsVoidPtr with non-C-object

- I think that's because its a pointer to the ctypes py_object() rather
than the PyCObject we are dealing with but I have no idea how to create
a pointer to that.

--
Gord Allott ([email protected])


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFI8CN1lVw7T9GIvRsRAuo0AKCSzSQgnnRPanYLStdBLGGIA669rQCeJsm7
G/Dnr2uDs8CaZJ988UnF2kU=
=/HxT
-----END PGP SIGNATURE-----
 
A

Aaron \Castironpi\ Brady

Aaron "Castironpi" Brady wrote:
snip
 Last, you
haven't mentioned an attempt with PyCObject_AsVoidPtr yet:
void* PyCObject_AsVoidPtr(PyObject* self)
    Return the object void * that the PyCObject self was created with.
Where does that get you?

sorry yes you were right, I was reading PyCObject_AsVoidPtr as
PyCObject_FromVoidPtr :)

using AsVoidPtr is a little confusing, this is the code I am using:
        display = pygame.display.get_wm_info()['display']
        pyobj = py_object(display)
        ref = pointer(pyobj)

        print pythonapi.PyCObject_AsVoidPtr(ref)

it produces the following traceback:
Traceback (most recent call last):
  File "pygametest.py", line 125, in <module>
    app = PyGameOGREApp()
  File "pygametest.py", line 33, in __init__
    self._createWindow(width, height, fullscreen)
  File "pygametest.py", line 64, in _createWindow
    print pythonapi.PyCObject_AsVoidPtr(ref)
TypeError: PyCObject_AsVoidPtr with non-C-object

- I think that's because its a pointer to the ctypes py_object() rather
than the PyCObject we are dealing with but I have no idea how to create
a pointer to that.

My pygame install just returns an integer in get_wm_info. Take a
look:
pygame.display.get_wm_info() {'window': 1180066, 'hglrc': 0}
pygame.display.get_wm_info()['window'] 1180066
ctypes.c_void_p( _ )
c_void_p(1180066)

You're suggesting yours looks like this:
{ ... 'display': ctypes.py_object( 1180066 ), ... }

What does type( display ) give you?
 
G

Gordon Allott

Aaron said:
My pygame install just returns an integer in get_wm_info. Take a
look:
pygame.display.get_wm_info() {'window': 1180066, 'hglrc': 0}
pygame.display.get_wm_info()['window'] 1180066
ctypes.c_void_p( _ )
c_void_p(1180066)

You're suggesting yours looks like this:
{ ... 'display': ctypes.py_object( 1180066 ), ... }

What does type( display ) give you?

yes its different on windows and linux, windows only has a few items
where linux has many more. 'window' is just the window 'id' at any rate
which is not the data I am after (which is internally an address to an
xlib structure)
this is what pygame.display.get_wm_info() returns on linux:
{'fswindow': 31457283, 'wmwindow': 31457284, 'window': 31457294,
'lock_func': <PyCObject object at 0x89dfa70>, 'unlock_func': <PyCObject
object at 0x89dfa88>, 'display': <PyCObject object at 0x89dfa58>}

note how the display object is a PyCObject, thats got the address I want
inside it.


--
Gord Allott ([email protected])


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFI8LwNlVw7T9GIvRsRAixJAJwIe97b5eJ3tUrfolqZ7D15DCsV8ACgp4UL
idODQg3cBrUXy5BxEezExtM=
=Jvca
-----END PGP SIGNATURE-----
 
A

Aaron \Castironpi\ Brady

Aaron said:
My pygame install just returns an integer in get_wm_info.  Take a
look:
pygame.display.get_wm_info()
{'window': 1180066, 'hglrc': 0}
pygame.display.get_wm_info()['window'] 1180066
ctypes.c_void_p( _ ) c_void_p(1180066)

You're suggesting yours looks like this:
pygame.display.get_wm_info()
{ ... 'display': ctypes.py_object( 1180066 ), ... }
What does type( display ) give you?

yes its different on windows and linux, windows only has a few items
where linux has many more. 'window' is just the window 'id'  at any rate
which is not the data I am after (which is internally an address to an
xlib structure)
this is what pygame.display.get_wm_info() returns on linux:
{'fswindow': 31457283, 'wmwindow': 31457284, 'window': 31457294,
'lock_func': <PyCObject object at 0x89dfa70>, 'unlock_func': <PyCObject
object at 0x89dfa88>, 'display': <PyCObject object at 0x89dfa58>}

note how the display object is a PyCObject, thats got the address I want
 inside it.

What does print pythonapi.PyCObject_AsVoidPtr(display) give you?
 
G

Gordon Allott

Aaron said:
What does print pythonapi.PyCObject_AsVoidPtr(display) give you?

Traceback (most recent call last):
File "pygametest.py", line 125, in <module>
app = PyGameOGREApp()
File "pygametest.py", line 33, in __init__
self._createWindow(width, height, fullscreen)
File "pygametest.py", line 65, in _createWindow
print pythonapi.PyCObject_AsVoidPtr(display)
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't
know how to convert parameter 1


--
Gord Allott ([email protected])


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFI8PeLlVw7T9GIvRsRAhJyAJ9BtoEeYhpXOPe6jtcFYQkfccdrTwCcCLbj
FIJ4SeuH1lwP+F5IV3JoV+A=
=uwxx
-----END PGP SIGNATURE-----
 
A

Aaron \Castironpi\ Brady

Traceback (most recent call last):
  File "pygametest.py", line 125, in <module>
    app = PyGameOGREApp()
  File "pygametest.py", line 33, in __init__
    self._createWindow(width, height, fullscreen)
  File "pygametest.py", line 65, in _createWindow
    print pythonapi.PyCObject_AsVoidPtr(display)
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't
know how to convert parameter 1

--
Gord Allott ([email protected])

 signature.asc
< 1KViewDownload

If anyone knows this better, feel free to step in.

Put this before the call:

ctypes.pythonapi.PyCObject_AsVoidPtr.restype = ctypes.c_void_p
ctypes.pythonapi.PyCObject_AsVoidPtr.argtypes = [ ctypes.py_object ]

The reason is that this is the default signature, which is wrong:

There are other ways to prototype it if you like, too.
 
G

Gordon Allott

thank you so much, this works perfectly :)


--
Gord Allott ([email protected])


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFI8QEJlVw7T9GIvRsRAuK2AJ9DmCWrRbpirVX3412i5qg6rQpOYQCfRDmw
eBbJD28vTEPZYch0jz2f8hM=
=yEi0
-----END PGP SIGNATURE-----
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top