Issue
Hey I got this code which i'm using to cast numpy 2d array to ctype double pointer.
import ctypes as ct
import numpy as np
arr = np.empty([500, 500], dtype=np.uint8)
UI8Ptr = ct.POINTER(ct.c_uint8)
UI8PtrPtr = ct.POINTER(UI8Ptr)
ct_arr = np.ctypeslib.as_ctypes(arr)
UI8PtrArr = UI8Ptr * ct_arr._length_
ct_ptr = ct.cast(UI8PtrArr(*(ct.cast(row, UI8Ptr) for row in ct_arr)), UI8PtrPtr)
How can i cast ct_ptr back to numpy 2d array?
Solution
Note: This is a follow up to [SO]: How to pass a 2d array from Python to C?.
One way would be going through the following states:
CTypes pointer
Python lists
NumPy array
2 observations automatically arise:
It's very inefficient, but unfortunately I'm not aware how to get rid of #2. (which is the culprit)
The pointer holds information about the base type, but not about the dimension(s) of the array it was created from, so you have to "save" them, as you'll need them when "deconstructing" the pointer
code00.py:
#!/usr/bin/env python3
import ctypes as ct
import sys
import numpy as np
def main(*argv):
dim0 = 3
dim1 = 4
arr0 = np.empty([dim0, dim1], dtype=np.uint8)
print("Initial array:\n{0:}".format(arr0))
UI8Ptr = ct.POINTER(ct.c_uint8)
UI8PtrPtr = ct.POINTER(UI8Ptr)
ct_arr = np.ctypeslib.as_ctypes(arr0)
UI8PtrArr = UI8Ptr * ct_arr._length_
ct_ptr = ct.cast(UI8PtrArr(*(ct.cast(row, UI8Ptr) for row in ct_arr)), UI8PtrPtr)
arr1 = np.array([[ct_ptr[i][j] for j in range(dim1)] for i in range(dim0)], dtype=ct_ptr._type_._type_._type_)
print("\nFinal array:\n{0:}".format(arr1))
print("\nEqual arrays: {0:}".format(np.array_equal(arr0, arr1)))
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.")
sys.exit(rc)
Output:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q058781199]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code00.py Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 064bit on win32 Initial array: [[ 96 100 101 115] [105 114 101 100] [ 96 96 32 115]] Final array: [[ 96 100 101 115] [105 114 101 100] [ 96 96 32 115]] Equal arrays: True Done.
Fore more info on this topic check [SO]: Numpy error when converting array of ctypes types to void pointer (@CristiFati's answer).
Answered By - CristiFati
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.