ctypes.cast.
>>> import ctypes
>>> c_long_p = ctypes.POINTER(ctypes.c_long)
>>> some_long = ctypes.c_long(42)
>>> ctypes.addressof(some_long)
4300833936
>>> ctypes.cast(4300833936, c_long_p)
<__main__.LP_c_long object at 0x1005983b0>
>>> ctypes.cast(4300833936, c_long_p).contents
c_long(42)
Answer from habnabit on Stack Overflowpython - Dereference void pointer to numpy array or list - Stack Overflow
python - Is it possible to dereference variable id's? - Stack Overflow
[FEAT] being able to enforce the dereferencing of the smart pointer in argument conversion
Why is there no concept of a pointer or pass-by reference in python? Is there something I can use
I can't test this right now, but this is what I would try:
import numpy as np
result = ...
shape = (10, 2)
array_size = np.prod(shape)
mem_size = 8 * array_size
array_str = ctypes.string_at(result, mem_size)
array = np.frombuffer(array_str, float, array_size).reshape(shape)
array will be read only, copy it if you need a writable array.
Here is a solution that uses ctypes.cast or numpy.ctypeslib.as_array, and no ctypes.string_at just in case if it makes an extra copy of memory region.
class _FFIArray(Structure):
_fields_ = [("data", c_void_p), ("len", c_size_t)]
class Coordinate(Structure):
_fields_ = [("latitude", c_double), ("longitude", c_double)]
class Coordinates(Structure):
_fields_ = [("data", POINTER(Coordinate)), ("len", c_size_t)]
decode_polyline = lib.decode_polyline_ffi
decode_polyline.argtypes = (c_char_p, c_uint32)
decode_polyline.restype = _FFIArray
# assuming that the second argument is the length of polyline,
# although it should not be needed for `\0` terminated string
res = decode_polyline(polyline, len(polyline))
nres = Coordinates(cast(res.data, POINTER(Coordinate)), res.len)
for i in range(nres.len):
print(nres.data[i].latitude, nres.data[i].longitude)
# if just a numpy (np) array is needed
xs = np.ctypeslib.as_array((c_double * res.len * 2).from_address(res.data))
# "New view of array with the same data."
xs = xs.view(dtype=[('a', np.float64), ('b', np.float64)], type=np.ndarray)
xs.shape = res.len
Here's a utility function based on a (now-deleted) comment made by "Tiran" in a weblog discussion @Hophat Abc references in his own answer that will work in both Python 2 and 3.
Disclaimer: If you read the the linked discussion, you'll find that some folks think this is so unsafe that it should never be used (as likewise mentioned in some of the comments below). I don't agree with that assessment but feel I should at least mention that there's some debate about using it.
import _ctypes
def di(obj_id):
""" Inverse of id() function. """
return _ctypes.PyObj_FromPtr(obj_id)
if __name__ == '__main__':
a = 42
b = 'answer'
print(di(id(a))) # -> 42
print(di(id(b))) # -> answer
Not easily.
You could recurse through the gc.get_objects() list, testing each and every object if it has the same id() but that's not very practical.
The id() function is not intended to be dereferenceable; the fact that it is based on the memory address is a CPython implementation detail, that other Python implementations do not follow.
I am a C++ and assembly developer mainly, but as someone entering the job market that just doesn't cut it. I have a job I got hired for where I'm taking 4+ years of a python codebase that no one has documented and is spaghetti and updating it, and was supposed to be adding multithreading (EXCEPT THERE IS NO TRUE MULTITHREADING SO I HAVE TO DO MULTIPROCESSING WHICH IS A CLUSTER-F***). So that blows.
BUT
why is there no pointers!? or way to go references? I need to store data in an object that gets passed into some libraries, and then the library runs callbacks where I analyze the crap. From there I need to set the values so in other callbacks I can work with the values. It's a dictionary so I can add some new keys to store the data... except I can't because it's like pass by value so the data instantly gets deleted once it returns from the callback. If I passed in a pointer I'd be set, except that's not possible...
That's just one issue in a mirad of issues I'm facing with this junk language. Not to even mention the horribleness of everything using like 2gb of memory because each process copies the entire memory space of the head process....
Please tell me there's some kinda object or pointer thing I can use.
EDIT : I got the help I needed here, thanks everyone! sorry to trash the language a bit above I was just frustrated lol
This can be done explicitly.
class ref:
def __init__(self, obj): self.obj = obj
def get(self): return self.obj
def set(self, obj): self.obj = obj
a = ref([1, 2])
b = a
print(a.get()) # => [1, 2]
print(b.get()) # => [1, 2]
b.set(2)
print(a.get()) # => 2
print(b.get()) # => 2
You may want to read Semantics of Python variable names from a C++ perspective. The bottom line: All variables are references.
More to the point, don't think in terms of variables, but in terms of objects which can be named.