Getting data from ctypes array into numpy












26















I am using a Python (via ctypes) wrapped C library to run a series of computation. At different stages of the running, I want to get data into Python, and specifically numpy arrays.



The wrapping I am using does two different types of return for array data (which is of particular interest to me):





  • ctypes Array: When I do type(x) (where x is the ctypes array, I get a <class 'module_name.wrapper_class_name.c_double_Array_12000'> in return. I know that this data is a copy of the internal data from the documentation and I am able to get it into a numpy array easily:



    >>> np.ctypeslib.as_array(x)



This returns a 1D numpy array of the data.





  • ctype pointer to data: In this case from the library's documentation, I understand that I am getting a pointer to the data stored and used directly to the library. Whey I do type(y) (where y is the pointer) I get <class 'module_name.wrapper_class_name.LP_c_double'>. With this case I am still able to index through the data like y[0][2], but I was only able to get it into numpy via a super awkward:



    >>> np.frombuffer(np.core.multiarray.int_asbuffer(
    ctypes.addressof(y.contents), array_length*np.dtype(float).itemsize))



I found this in an old numpy mailing list thread from Travis Oliphant, but not in the numpy documentation. If instead of this approach I try as above I get the following:



>>> np.ctypeslib.as_array(y)
...
... BUNCH OF STACK INFORMATION
...
AttributeError: 'LP_c_double' object has no attribute '__array_interface__'


Is this np.frombuffer approach the best or only way to do this? I am open to other suggestions but must would still like to use numpy as I have a lot of other post-processing code that relies on numpy functionality that I want to use with this data.










share|improve this question

























  • Do you have control over the C lib? Could you change the API of the library?

    – Sven Marnach
    Dec 4 '10 at 20:03











  • Yes - I have the source. I'm not sure which way to go though, as the pointer approach allows Python to directly act on the data which I suppose in some cases could be an advantage. In my case though, yes it would be an advantage to have everything come out as a ctype array. Any recommendations?

    – dtlussier
    Dec 4 '10 at 20:09






  • 1





    I would suggest to make the library use an (NumPy-) array you allocate in Python and pass on to the library. That way, you can act on the same memory, but you don't have to bother to do any awkward conversions. You already have a NumPy array, and passing it to a library is well-supported by using numpy.ctypeslib.ndpointer as argument type to the ctypes wrapper of your function. (If this is not clear, just ask...)

    – Sven Marnach
    Dec 4 '10 at 20:46


















26















I am using a Python (via ctypes) wrapped C library to run a series of computation. At different stages of the running, I want to get data into Python, and specifically numpy arrays.



The wrapping I am using does two different types of return for array data (which is of particular interest to me):





  • ctypes Array: When I do type(x) (where x is the ctypes array, I get a <class 'module_name.wrapper_class_name.c_double_Array_12000'> in return. I know that this data is a copy of the internal data from the documentation and I am able to get it into a numpy array easily:



    >>> np.ctypeslib.as_array(x)



This returns a 1D numpy array of the data.





  • ctype pointer to data: In this case from the library's documentation, I understand that I am getting a pointer to the data stored and used directly to the library. Whey I do type(y) (where y is the pointer) I get <class 'module_name.wrapper_class_name.LP_c_double'>. With this case I am still able to index through the data like y[0][2], but I was only able to get it into numpy via a super awkward:



    >>> np.frombuffer(np.core.multiarray.int_asbuffer(
    ctypes.addressof(y.contents), array_length*np.dtype(float).itemsize))



I found this in an old numpy mailing list thread from Travis Oliphant, but not in the numpy documentation. If instead of this approach I try as above I get the following:



>>> np.ctypeslib.as_array(y)
...
... BUNCH OF STACK INFORMATION
...
AttributeError: 'LP_c_double' object has no attribute '__array_interface__'


Is this np.frombuffer approach the best or only way to do this? I am open to other suggestions but must would still like to use numpy as I have a lot of other post-processing code that relies on numpy functionality that I want to use with this data.










share|improve this question

























  • Do you have control over the C lib? Could you change the API of the library?

    – Sven Marnach
    Dec 4 '10 at 20:03











  • Yes - I have the source. I'm not sure which way to go though, as the pointer approach allows Python to directly act on the data which I suppose in some cases could be an advantage. In my case though, yes it would be an advantage to have everything come out as a ctype array. Any recommendations?

    – dtlussier
    Dec 4 '10 at 20:09






  • 1





    I would suggest to make the library use an (NumPy-) array you allocate in Python and pass on to the library. That way, you can act on the same memory, but you don't have to bother to do any awkward conversions. You already have a NumPy array, and passing it to a library is well-supported by using numpy.ctypeslib.ndpointer as argument type to the ctypes wrapper of your function. (If this is not clear, just ask...)

    – Sven Marnach
    Dec 4 '10 at 20:46
















26












26








26


15






I am using a Python (via ctypes) wrapped C library to run a series of computation. At different stages of the running, I want to get data into Python, and specifically numpy arrays.



The wrapping I am using does two different types of return for array data (which is of particular interest to me):





  • ctypes Array: When I do type(x) (where x is the ctypes array, I get a <class 'module_name.wrapper_class_name.c_double_Array_12000'> in return. I know that this data is a copy of the internal data from the documentation and I am able to get it into a numpy array easily:



    >>> np.ctypeslib.as_array(x)



This returns a 1D numpy array of the data.





  • ctype pointer to data: In this case from the library's documentation, I understand that I am getting a pointer to the data stored and used directly to the library. Whey I do type(y) (where y is the pointer) I get <class 'module_name.wrapper_class_name.LP_c_double'>. With this case I am still able to index through the data like y[0][2], but I was only able to get it into numpy via a super awkward:



    >>> np.frombuffer(np.core.multiarray.int_asbuffer(
    ctypes.addressof(y.contents), array_length*np.dtype(float).itemsize))



I found this in an old numpy mailing list thread from Travis Oliphant, but not in the numpy documentation. If instead of this approach I try as above I get the following:



>>> np.ctypeslib.as_array(y)
...
... BUNCH OF STACK INFORMATION
...
AttributeError: 'LP_c_double' object has no attribute '__array_interface__'


Is this np.frombuffer approach the best or only way to do this? I am open to other suggestions but must would still like to use numpy as I have a lot of other post-processing code that relies on numpy functionality that I want to use with this data.










share|improve this question
















I am using a Python (via ctypes) wrapped C library to run a series of computation. At different stages of the running, I want to get data into Python, and specifically numpy arrays.



The wrapping I am using does two different types of return for array data (which is of particular interest to me):





  • ctypes Array: When I do type(x) (where x is the ctypes array, I get a <class 'module_name.wrapper_class_name.c_double_Array_12000'> in return. I know that this data is a copy of the internal data from the documentation and I am able to get it into a numpy array easily:



    >>> np.ctypeslib.as_array(x)



This returns a 1D numpy array of the data.





  • ctype pointer to data: In this case from the library's documentation, I understand that I am getting a pointer to the data stored and used directly to the library. Whey I do type(y) (where y is the pointer) I get <class 'module_name.wrapper_class_name.LP_c_double'>. With this case I am still able to index through the data like y[0][2], but I was only able to get it into numpy via a super awkward:



    >>> np.frombuffer(np.core.multiarray.int_asbuffer(
    ctypes.addressof(y.contents), array_length*np.dtype(float).itemsize))



I found this in an old numpy mailing list thread from Travis Oliphant, but not in the numpy documentation. If instead of this approach I try as above I get the following:



>>> np.ctypeslib.as_array(y)
...
... BUNCH OF STACK INFORMATION
...
AttributeError: 'LP_c_double' object has no attribute '__array_interface__'


Is this np.frombuffer approach the best or only way to do this? I am open to other suggestions but must would still like to use numpy as I have a lot of other post-processing code that relies on numpy functionality that I want to use with this data.







python numpy ctypes






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 4 '10 at 20:40







dtlussier

















asked Dec 4 '10 at 19:58









dtlussierdtlussier

1,71421622




1,71421622













  • Do you have control over the C lib? Could you change the API of the library?

    – Sven Marnach
    Dec 4 '10 at 20:03











  • Yes - I have the source. I'm not sure which way to go though, as the pointer approach allows Python to directly act on the data which I suppose in some cases could be an advantage. In my case though, yes it would be an advantage to have everything come out as a ctype array. Any recommendations?

    – dtlussier
    Dec 4 '10 at 20:09






  • 1





    I would suggest to make the library use an (NumPy-) array you allocate in Python and pass on to the library. That way, you can act on the same memory, but you don't have to bother to do any awkward conversions. You already have a NumPy array, and passing it to a library is well-supported by using numpy.ctypeslib.ndpointer as argument type to the ctypes wrapper of your function. (If this is not clear, just ask...)

    – Sven Marnach
    Dec 4 '10 at 20:46





















  • Do you have control over the C lib? Could you change the API of the library?

    – Sven Marnach
    Dec 4 '10 at 20:03











  • Yes - I have the source. I'm not sure which way to go though, as the pointer approach allows Python to directly act on the data which I suppose in some cases could be an advantage. In my case though, yes it would be an advantage to have everything come out as a ctype array. Any recommendations?

    – dtlussier
    Dec 4 '10 at 20:09






  • 1





    I would suggest to make the library use an (NumPy-) array you allocate in Python and pass on to the library. That way, you can act on the same memory, but you don't have to bother to do any awkward conversions. You already have a NumPy array, and passing it to a library is well-supported by using numpy.ctypeslib.ndpointer as argument type to the ctypes wrapper of your function. (If this is not clear, just ask...)

    – Sven Marnach
    Dec 4 '10 at 20:46



















Do you have control over the C lib? Could you change the API of the library?

– Sven Marnach
Dec 4 '10 at 20:03





Do you have control over the C lib? Could you change the API of the library?

– Sven Marnach
Dec 4 '10 at 20:03













Yes - I have the source. I'm not sure which way to go though, as the pointer approach allows Python to directly act on the data which I suppose in some cases could be an advantage. In my case though, yes it would be an advantage to have everything come out as a ctype array. Any recommendations?

– dtlussier
Dec 4 '10 at 20:09





Yes - I have the source. I'm not sure which way to go though, as the pointer approach allows Python to directly act on the data which I suppose in some cases could be an advantage. In my case though, yes it would be an advantage to have everything come out as a ctype array. Any recommendations?

– dtlussier
Dec 4 '10 at 20:09




1




1





I would suggest to make the library use an (NumPy-) array you allocate in Python and pass on to the library. That way, you can act on the same memory, but you don't have to bother to do any awkward conversions. You already have a NumPy array, and passing it to a library is well-supported by using numpy.ctypeslib.ndpointer as argument type to the ctypes wrapper of your function. (If this is not clear, just ask...)

– Sven Marnach
Dec 4 '10 at 20:46







I would suggest to make the library use an (NumPy-) array you allocate in Python and pass on to the library. That way, you can act on the same memory, but you don't have to bother to do any awkward conversions. You already have a NumPy array, and passing it to a library is well-supported by using numpy.ctypeslib.ndpointer as argument type to the ctypes wrapper of your function. (If this is not clear, just ask...)

– Sven Marnach
Dec 4 '10 at 20:46














5 Answers
5






active

oldest

votes


















25














Creating NumPy arrays from a ctypes pointer object is a problematic operation. It is unclear who actually owns the memory the pointer is pointing to. When will it be freed again? How long is it valid? Whenever possible I would try to avoid this kind of construct. It is so much easier and safer to create arrays in the Python code and pass them to the C function than to use memory allocated by a Python-unaware C function. By doing the latter, you negate to some extent the advantages of having a high-level language taking care of the memory management.



If you are really sure that someone takes care of the memory, you can create an object exposing the Python "buffer protocol" and then create a NumPy array using this buffer object. You gave one way of creating the buffer object in your post, via the undocumented int_asbuffer() function:



buffer = numpy.core.multiarray.int_asbuffer(
ctypes.addressof(y.contents), 8*array_length)


(Note that I substituted 8 for np.dtype(float).itemsize. It's always 8, on any platform.) A different way to create the buffer object would be to call the PyBuffer_FromMemory() function from the Python C API via ctypes:



buffer_from_memory = ctypes.pythonapi.PyBuffer_FromMemory
buffer_from_memory.restype = ctypes.py_object
buffer = buffer_from_memory(y, 8*array_length)


For both these ways, you can create a NumPy array from buffer by



a = numpy.frombuffer(buffer, float)


(I actually do not understand why you use .astype() instead of a second parameter to frombuffer; furthermore, I wonder why you use np.int, while you said earlier that the array contains doubles.)



I'm afraid it won't get much easier than this, but it isn't that bad, don't you think? You could bury all the ugly details in a wrapper function and don't worry about it any more.






share|improve this answer
























  • That's great - thanks for the overview of the pros and cons. the .astype() call was just an accidental copy and past error. I've pulled it out of my question now. Thanks for picking up on that.

    – dtlussier
    Dec 4 '10 at 20:42






  • 1





    For python3, you can use PyMemoryView_FromMemory, not PyBuffer_FromMemory. Many things that were previously called buffers are now called memoryviews.

    – bombs
    Sep 4 '18 at 17:58



















9














Another possibility (which may require more recent versions of libraries than is available when the first answer was written -- I tested something similar with ctypes 1.1.0 and numpy 1.5.0b2) is to convert from the pointer to the array.



np.ctypeslib.as_array(
(ctypes.c_double * array_length).from_address(ctypes.addressof(y.contents)))


This seems to still have the shared ownership semantics, so you probably need to make sure that you free the underlying buffer eventually.






share|improve this answer



















  • 2





    Or without special support from numpy: you could convert y pointer to a pointer to an array type: ap = ctypes.cast(y, ctypes.POINTER(ArrayType)) where ArrayType = ctypes.c_double * array_length and create numpy array from that: a = np.frombuffer(ap.contents). See How to convert pointer to c array to python array

    – jfs
    Jan 19 '13 at 18:28











  • I was trying this, but the ap object don't have a member, contents.

    – Totte Karlsson
    Mar 7 '14 at 22:19











  • @TotteKarlsson: the code from the link works as is (I've tested it). It is probably a bug in your code (it may also be a difference between various Python versions but it is less likely). If you haven't fixed it; create a minimal but complete code example, specify what is your OS, python version and post it as a new SO question

    – jfs
    Oct 20 '15 at 10:52



















8














Neither of these worked for me in Python 3. As a general solution for converting a ctypes pointer into a numpy ndarray in python 2 and 3 I found this worked (via getting a read-only buffer):



def make_nd_array(c_pointer, shape, dtype=np.float64, order='C', own_data=True):
arr_size = np.prod(shape[:]) * np.dtype(dtype).itemsize
if sys.version_info.major >= 3:
buf_from_mem = ctypes.pythonapi.PyMemoryView_FromMemory
buf_from_mem.restype = ctypes.py_object
buf_from_mem.argtypes = (ctypes.c_void_p, ctypes.c_int, ctypes.c_int)
buffer = buf_from_mem(c_pointer, arr_size, 0x100)
else:
buf_from_mem = ctypes.pythonapi.PyBuffer_FromMemory
buf_from_mem.restype = ctypes.py_object
buffer = buf_from_mem(c_pointer, arr_size)
arr = np.ndarray(tuple(shape[:]), dtype, buffer, order=order)
if own_data and not arr.flags.owndata:
return arr.copy()
else:
return arr





share|improve this answer


























  • This is awesome! Array comes out rotated - weird :)

    – jtlz2
    Mar 23 '18 at 14:56



















0














If you are ok with creating arrays in python, the following example with 2d array works in python3:



import numpy as np
import ctypes

OutType = (ctypes.c_float * 4) * 6
out = OutType()
YourCfunction = ctypes.CDLL('./yourlib.so').voidreturningfunctionwithweirdname
YourCfunction.argtypes = [ctypes.POINTER(ctypes.c_float)]*3, ctypes.POINTER(ctypes.c_float)]*5, OutType]
YourCfunction(input1, input2, out)
out = np.array(out) # convert it to numpy

print(out)


numpy and ctypes versions are 1.11.1 and 1.1.0






share|improve this answer

































    0














    np.ctypeslib.as_array is all you need here.



    From an array:



     c_arr = (c_float * 8)()
    np.ctypeslib.as_array(c_arr)


    From a pointer



     c_arr = (c_float * 8)()
    ptr = ctypes.pointer(c_arr[0])
    np.ctypeslib.as_array(ptr, shape=(8,))





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4355524%2fgetting-data-from-ctypes-array-into-numpy%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      25














      Creating NumPy arrays from a ctypes pointer object is a problematic operation. It is unclear who actually owns the memory the pointer is pointing to. When will it be freed again? How long is it valid? Whenever possible I would try to avoid this kind of construct. It is so much easier and safer to create arrays in the Python code and pass them to the C function than to use memory allocated by a Python-unaware C function. By doing the latter, you negate to some extent the advantages of having a high-level language taking care of the memory management.



      If you are really sure that someone takes care of the memory, you can create an object exposing the Python "buffer protocol" and then create a NumPy array using this buffer object. You gave one way of creating the buffer object in your post, via the undocumented int_asbuffer() function:



      buffer = numpy.core.multiarray.int_asbuffer(
      ctypes.addressof(y.contents), 8*array_length)


      (Note that I substituted 8 for np.dtype(float).itemsize. It's always 8, on any platform.) A different way to create the buffer object would be to call the PyBuffer_FromMemory() function from the Python C API via ctypes:



      buffer_from_memory = ctypes.pythonapi.PyBuffer_FromMemory
      buffer_from_memory.restype = ctypes.py_object
      buffer = buffer_from_memory(y, 8*array_length)


      For both these ways, you can create a NumPy array from buffer by



      a = numpy.frombuffer(buffer, float)


      (I actually do not understand why you use .astype() instead of a second parameter to frombuffer; furthermore, I wonder why you use np.int, while you said earlier that the array contains doubles.)



      I'm afraid it won't get much easier than this, but it isn't that bad, don't you think? You could bury all the ugly details in a wrapper function and don't worry about it any more.






      share|improve this answer
























      • That's great - thanks for the overview of the pros and cons. the .astype() call was just an accidental copy and past error. I've pulled it out of my question now. Thanks for picking up on that.

        – dtlussier
        Dec 4 '10 at 20:42






      • 1





        For python3, you can use PyMemoryView_FromMemory, not PyBuffer_FromMemory. Many things that were previously called buffers are now called memoryviews.

        – bombs
        Sep 4 '18 at 17:58
















      25














      Creating NumPy arrays from a ctypes pointer object is a problematic operation. It is unclear who actually owns the memory the pointer is pointing to. When will it be freed again? How long is it valid? Whenever possible I would try to avoid this kind of construct. It is so much easier and safer to create arrays in the Python code and pass them to the C function than to use memory allocated by a Python-unaware C function. By doing the latter, you negate to some extent the advantages of having a high-level language taking care of the memory management.



      If you are really sure that someone takes care of the memory, you can create an object exposing the Python "buffer protocol" and then create a NumPy array using this buffer object. You gave one way of creating the buffer object in your post, via the undocumented int_asbuffer() function:



      buffer = numpy.core.multiarray.int_asbuffer(
      ctypes.addressof(y.contents), 8*array_length)


      (Note that I substituted 8 for np.dtype(float).itemsize. It's always 8, on any platform.) A different way to create the buffer object would be to call the PyBuffer_FromMemory() function from the Python C API via ctypes:



      buffer_from_memory = ctypes.pythonapi.PyBuffer_FromMemory
      buffer_from_memory.restype = ctypes.py_object
      buffer = buffer_from_memory(y, 8*array_length)


      For both these ways, you can create a NumPy array from buffer by



      a = numpy.frombuffer(buffer, float)


      (I actually do not understand why you use .astype() instead of a second parameter to frombuffer; furthermore, I wonder why you use np.int, while you said earlier that the array contains doubles.)



      I'm afraid it won't get much easier than this, but it isn't that bad, don't you think? You could bury all the ugly details in a wrapper function and don't worry about it any more.






      share|improve this answer
























      • That's great - thanks for the overview of the pros and cons. the .astype() call was just an accidental copy and past error. I've pulled it out of my question now. Thanks for picking up on that.

        – dtlussier
        Dec 4 '10 at 20:42






      • 1





        For python3, you can use PyMemoryView_FromMemory, not PyBuffer_FromMemory. Many things that were previously called buffers are now called memoryviews.

        – bombs
        Sep 4 '18 at 17:58














      25












      25








      25







      Creating NumPy arrays from a ctypes pointer object is a problematic operation. It is unclear who actually owns the memory the pointer is pointing to. When will it be freed again? How long is it valid? Whenever possible I would try to avoid this kind of construct. It is so much easier and safer to create arrays in the Python code and pass them to the C function than to use memory allocated by a Python-unaware C function. By doing the latter, you negate to some extent the advantages of having a high-level language taking care of the memory management.



      If you are really sure that someone takes care of the memory, you can create an object exposing the Python "buffer protocol" and then create a NumPy array using this buffer object. You gave one way of creating the buffer object in your post, via the undocumented int_asbuffer() function:



      buffer = numpy.core.multiarray.int_asbuffer(
      ctypes.addressof(y.contents), 8*array_length)


      (Note that I substituted 8 for np.dtype(float).itemsize. It's always 8, on any platform.) A different way to create the buffer object would be to call the PyBuffer_FromMemory() function from the Python C API via ctypes:



      buffer_from_memory = ctypes.pythonapi.PyBuffer_FromMemory
      buffer_from_memory.restype = ctypes.py_object
      buffer = buffer_from_memory(y, 8*array_length)


      For both these ways, you can create a NumPy array from buffer by



      a = numpy.frombuffer(buffer, float)


      (I actually do not understand why you use .astype() instead of a second parameter to frombuffer; furthermore, I wonder why you use np.int, while you said earlier that the array contains doubles.)



      I'm afraid it won't get much easier than this, but it isn't that bad, don't you think? You could bury all the ugly details in a wrapper function and don't worry about it any more.






      share|improve this answer













      Creating NumPy arrays from a ctypes pointer object is a problematic operation. It is unclear who actually owns the memory the pointer is pointing to. When will it be freed again? How long is it valid? Whenever possible I would try to avoid this kind of construct. It is so much easier and safer to create arrays in the Python code and pass them to the C function than to use memory allocated by a Python-unaware C function. By doing the latter, you negate to some extent the advantages of having a high-level language taking care of the memory management.



      If you are really sure that someone takes care of the memory, you can create an object exposing the Python "buffer protocol" and then create a NumPy array using this buffer object. You gave one way of creating the buffer object in your post, via the undocumented int_asbuffer() function:



      buffer = numpy.core.multiarray.int_asbuffer(
      ctypes.addressof(y.contents), 8*array_length)


      (Note that I substituted 8 for np.dtype(float).itemsize. It's always 8, on any platform.) A different way to create the buffer object would be to call the PyBuffer_FromMemory() function from the Python C API via ctypes:



      buffer_from_memory = ctypes.pythonapi.PyBuffer_FromMemory
      buffer_from_memory.restype = ctypes.py_object
      buffer = buffer_from_memory(y, 8*array_length)


      For both these ways, you can create a NumPy array from buffer by



      a = numpy.frombuffer(buffer, float)


      (I actually do not understand why you use .astype() instead of a second parameter to frombuffer; furthermore, I wonder why you use np.int, while you said earlier that the array contains doubles.)



      I'm afraid it won't get much easier than this, but it isn't that bad, don't you think? You could bury all the ugly details in a wrapper function and don't worry about it any more.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Dec 4 '10 at 20:36









      Sven MarnachSven Marnach

      352k79748695




      352k79748695













      • That's great - thanks for the overview of the pros and cons. the .astype() call was just an accidental copy and past error. I've pulled it out of my question now. Thanks for picking up on that.

        – dtlussier
        Dec 4 '10 at 20:42






      • 1





        For python3, you can use PyMemoryView_FromMemory, not PyBuffer_FromMemory. Many things that were previously called buffers are now called memoryviews.

        – bombs
        Sep 4 '18 at 17:58



















      • That's great - thanks for the overview of the pros and cons. the .astype() call was just an accidental copy and past error. I've pulled it out of my question now. Thanks for picking up on that.

        – dtlussier
        Dec 4 '10 at 20:42






      • 1





        For python3, you can use PyMemoryView_FromMemory, not PyBuffer_FromMemory. Many things that were previously called buffers are now called memoryviews.

        – bombs
        Sep 4 '18 at 17:58

















      That's great - thanks for the overview of the pros and cons. the .astype() call was just an accidental copy and past error. I've pulled it out of my question now. Thanks for picking up on that.

      – dtlussier
      Dec 4 '10 at 20:42





      That's great - thanks for the overview of the pros and cons. the .astype() call was just an accidental copy and past error. I've pulled it out of my question now. Thanks for picking up on that.

      – dtlussier
      Dec 4 '10 at 20:42




      1




      1





      For python3, you can use PyMemoryView_FromMemory, not PyBuffer_FromMemory. Many things that were previously called buffers are now called memoryviews.

      – bombs
      Sep 4 '18 at 17:58





      For python3, you can use PyMemoryView_FromMemory, not PyBuffer_FromMemory. Many things that were previously called buffers are now called memoryviews.

      – bombs
      Sep 4 '18 at 17:58













      9














      Another possibility (which may require more recent versions of libraries than is available when the first answer was written -- I tested something similar with ctypes 1.1.0 and numpy 1.5.0b2) is to convert from the pointer to the array.



      np.ctypeslib.as_array(
      (ctypes.c_double * array_length).from_address(ctypes.addressof(y.contents)))


      This seems to still have the shared ownership semantics, so you probably need to make sure that you free the underlying buffer eventually.






      share|improve this answer



















      • 2





        Or without special support from numpy: you could convert y pointer to a pointer to an array type: ap = ctypes.cast(y, ctypes.POINTER(ArrayType)) where ArrayType = ctypes.c_double * array_length and create numpy array from that: a = np.frombuffer(ap.contents). See How to convert pointer to c array to python array

        – jfs
        Jan 19 '13 at 18:28











      • I was trying this, but the ap object don't have a member, contents.

        – Totte Karlsson
        Mar 7 '14 at 22:19











      • @TotteKarlsson: the code from the link works as is (I've tested it). It is probably a bug in your code (it may also be a difference between various Python versions but it is less likely). If you haven't fixed it; create a minimal but complete code example, specify what is your OS, python version and post it as a new SO question

        – jfs
        Oct 20 '15 at 10:52
















      9














      Another possibility (which may require more recent versions of libraries than is available when the first answer was written -- I tested something similar with ctypes 1.1.0 and numpy 1.5.0b2) is to convert from the pointer to the array.



      np.ctypeslib.as_array(
      (ctypes.c_double * array_length).from_address(ctypes.addressof(y.contents)))


      This seems to still have the shared ownership semantics, so you probably need to make sure that you free the underlying buffer eventually.






      share|improve this answer



















      • 2





        Or without special support from numpy: you could convert y pointer to a pointer to an array type: ap = ctypes.cast(y, ctypes.POINTER(ArrayType)) where ArrayType = ctypes.c_double * array_length and create numpy array from that: a = np.frombuffer(ap.contents). See How to convert pointer to c array to python array

        – jfs
        Jan 19 '13 at 18:28











      • I was trying this, but the ap object don't have a member, contents.

        – Totte Karlsson
        Mar 7 '14 at 22:19











      • @TotteKarlsson: the code from the link works as is (I've tested it). It is probably a bug in your code (it may also be a difference between various Python versions but it is less likely). If you haven't fixed it; create a minimal but complete code example, specify what is your OS, python version and post it as a new SO question

        – jfs
        Oct 20 '15 at 10:52














      9












      9








      9







      Another possibility (which may require more recent versions of libraries than is available when the first answer was written -- I tested something similar with ctypes 1.1.0 and numpy 1.5.0b2) is to convert from the pointer to the array.



      np.ctypeslib.as_array(
      (ctypes.c_double * array_length).from_address(ctypes.addressof(y.contents)))


      This seems to still have the shared ownership semantics, so you probably need to make sure that you free the underlying buffer eventually.






      share|improve this answer













      Another possibility (which may require more recent versions of libraries than is available when the first answer was written -- I tested something similar with ctypes 1.1.0 and numpy 1.5.0b2) is to convert from the pointer to the array.



      np.ctypeslib.as_array(
      (ctypes.c_double * array_length).from_address(ctypes.addressof(y.contents)))


      This seems to still have the shared ownership semantics, so you probably need to make sure that you free the underlying buffer eventually.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Nov 20 '12 at 20:36









      seekerseeker

      66611014




      66611014








      • 2





        Or without special support from numpy: you could convert y pointer to a pointer to an array type: ap = ctypes.cast(y, ctypes.POINTER(ArrayType)) where ArrayType = ctypes.c_double * array_length and create numpy array from that: a = np.frombuffer(ap.contents). See How to convert pointer to c array to python array

        – jfs
        Jan 19 '13 at 18:28











      • I was trying this, but the ap object don't have a member, contents.

        – Totte Karlsson
        Mar 7 '14 at 22:19











      • @TotteKarlsson: the code from the link works as is (I've tested it). It is probably a bug in your code (it may also be a difference between various Python versions but it is less likely). If you haven't fixed it; create a minimal but complete code example, specify what is your OS, python version and post it as a new SO question

        – jfs
        Oct 20 '15 at 10:52














      • 2





        Or without special support from numpy: you could convert y pointer to a pointer to an array type: ap = ctypes.cast(y, ctypes.POINTER(ArrayType)) where ArrayType = ctypes.c_double * array_length and create numpy array from that: a = np.frombuffer(ap.contents). See How to convert pointer to c array to python array

        – jfs
        Jan 19 '13 at 18:28











      • I was trying this, but the ap object don't have a member, contents.

        – Totte Karlsson
        Mar 7 '14 at 22:19











      • @TotteKarlsson: the code from the link works as is (I've tested it). It is probably a bug in your code (it may also be a difference between various Python versions but it is less likely). If you haven't fixed it; create a minimal but complete code example, specify what is your OS, python version and post it as a new SO question

        – jfs
        Oct 20 '15 at 10:52








      2




      2





      Or without special support from numpy: you could convert y pointer to a pointer to an array type: ap = ctypes.cast(y, ctypes.POINTER(ArrayType)) where ArrayType = ctypes.c_double * array_length and create numpy array from that: a = np.frombuffer(ap.contents). See How to convert pointer to c array to python array

      – jfs
      Jan 19 '13 at 18:28





      Or without special support from numpy: you could convert y pointer to a pointer to an array type: ap = ctypes.cast(y, ctypes.POINTER(ArrayType)) where ArrayType = ctypes.c_double * array_length and create numpy array from that: a = np.frombuffer(ap.contents). See How to convert pointer to c array to python array

      – jfs
      Jan 19 '13 at 18:28













      I was trying this, but the ap object don't have a member, contents.

      – Totte Karlsson
      Mar 7 '14 at 22:19





      I was trying this, but the ap object don't have a member, contents.

      – Totte Karlsson
      Mar 7 '14 at 22:19













      @TotteKarlsson: the code from the link works as is (I've tested it). It is probably a bug in your code (it may also be a difference between various Python versions but it is less likely). If you haven't fixed it; create a minimal but complete code example, specify what is your OS, python version and post it as a new SO question

      – jfs
      Oct 20 '15 at 10:52





      @TotteKarlsson: the code from the link works as is (I've tested it). It is probably a bug in your code (it may also be a difference between various Python versions but it is less likely). If you haven't fixed it; create a minimal but complete code example, specify what is your OS, python version and post it as a new SO question

      – jfs
      Oct 20 '15 at 10:52











      8














      Neither of these worked for me in Python 3. As a general solution for converting a ctypes pointer into a numpy ndarray in python 2 and 3 I found this worked (via getting a read-only buffer):



      def make_nd_array(c_pointer, shape, dtype=np.float64, order='C', own_data=True):
      arr_size = np.prod(shape[:]) * np.dtype(dtype).itemsize
      if sys.version_info.major >= 3:
      buf_from_mem = ctypes.pythonapi.PyMemoryView_FromMemory
      buf_from_mem.restype = ctypes.py_object
      buf_from_mem.argtypes = (ctypes.c_void_p, ctypes.c_int, ctypes.c_int)
      buffer = buf_from_mem(c_pointer, arr_size, 0x100)
      else:
      buf_from_mem = ctypes.pythonapi.PyBuffer_FromMemory
      buf_from_mem.restype = ctypes.py_object
      buffer = buf_from_mem(c_pointer, arr_size)
      arr = np.ndarray(tuple(shape[:]), dtype, buffer, order=order)
      if own_data and not arr.flags.owndata:
      return arr.copy()
      else:
      return arr





      share|improve this answer


























      • This is awesome! Array comes out rotated - weird :)

        – jtlz2
        Mar 23 '18 at 14:56
















      8














      Neither of these worked for me in Python 3. As a general solution for converting a ctypes pointer into a numpy ndarray in python 2 and 3 I found this worked (via getting a read-only buffer):



      def make_nd_array(c_pointer, shape, dtype=np.float64, order='C', own_data=True):
      arr_size = np.prod(shape[:]) * np.dtype(dtype).itemsize
      if sys.version_info.major >= 3:
      buf_from_mem = ctypes.pythonapi.PyMemoryView_FromMemory
      buf_from_mem.restype = ctypes.py_object
      buf_from_mem.argtypes = (ctypes.c_void_p, ctypes.c_int, ctypes.c_int)
      buffer = buf_from_mem(c_pointer, arr_size, 0x100)
      else:
      buf_from_mem = ctypes.pythonapi.PyBuffer_FromMemory
      buf_from_mem.restype = ctypes.py_object
      buffer = buf_from_mem(c_pointer, arr_size)
      arr = np.ndarray(tuple(shape[:]), dtype, buffer, order=order)
      if own_data and not arr.flags.owndata:
      return arr.copy()
      else:
      return arr





      share|improve this answer


























      • This is awesome! Array comes out rotated - weird :)

        – jtlz2
        Mar 23 '18 at 14:56














      8












      8








      8







      Neither of these worked for me in Python 3. As a general solution for converting a ctypes pointer into a numpy ndarray in python 2 and 3 I found this worked (via getting a read-only buffer):



      def make_nd_array(c_pointer, shape, dtype=np.float64, order='C', own_data=True):
      arr_size = np.prod(shape[:]) * np.dtype(dtype).itemsize
      if sys.version_info.major >= 3:
      buf_from_mem = ctypes.pythonapi.PyMemoryView_FromMemory
      buf_from_mem.restype = ctypes.py_object
      buf_from_mem.argtypes = (ctypes.c_void_p, ctypes.c_int, ctypes.c_int)
      buffer = buf_from_mem(c_pointer, arr_size, 0x100)
      else:
      buf_from_mem = ctypes.pythonapi.PyBuffer_FromMemory
      buf_from_mem.restype = ctypes.py_object
      buffer = buf_from_mem(c_pointer, arr_size)
      arr = np.ndarray(tuple(shape[:]), dtype, buffer, order=order)
      if own_data and not arr.flags.owndata:
      return arr.copy()
      else:
      return arr





      share|improve this answer















      Neither of these worked for me in Python 3. As a general solution for converting a ctypes pointer into a numpy ndarray in python 2 and 3 I found this worked (via getting a read-only buffer):



      def make_nd_array(c_pointer, shape, dtype=np.float64, order='C', own_data=True):
      arr_size = np.prod(shape[:]) * np.dtype(dtype).itemsize
      if sys.version_info.major >= 3:
      buf_from_mem = ctypes.pythonapi.PyMemoryView_FromMemory
      buf_from_mem.restype = ctypes.py_object
      buf_from_mem.argtypes = (ctypes.c_void_p, ctypes.c_int, ctypes.c_int)
      buffer = buf_from_mem(c_pointer, arr_size, 0x100)
      else:
      buf_from_mem = ctypes.pythonapi.PyBuffer_FromMemory
      buf_from_mem.restype = ctypes.py_object
      buffer = buf_from_mem(c_pointer, arr_size)
      arr = np.ndarray(tuple(shape[:]), dtype, buffer, order=order)
      if own_data and not arr.flags.owndata:
      return arr.copy()
      else:
      return arr






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 20 '15 at 22:35

























      answered Nov 20 '15 at 22:30









      wordywordy

      34939




      34939













      • This is awesome! Array comes out rotated - weird :)

        – jtlz2
        Mar 23 '18 at 14:56



















      • This is awesome! Array comes out rotated - weird :)

        – jtlz2
        Mar 23 '18 at 14:56

















      This is awesome! Array comes out rotated - weird :)

      – jtlz2
      Mar 23 '18 at 14:56





      This is awesome! Array comes out rotated - weird :)

      – jtlz2
      Mar 23 '18 at 14:56











      0














      If you are ok with creating arrays in python, the following example with 2d array works in python3:



      import numpy as np
      import ctypes

      OutType = (ctypes.c_float * 4) * 6
      out = OutType()
      YourCfunction = ctypes.CDLL('./yourlib.so').voidreturningfunctionwithweirdname
      YourCfunction.argtypes = [ctypes.POINTER(ctypes.c_float)]*3, ctypes.POINTER(ctypes.c_float)]*5, OutType]
      YourCfunction(input1, input2, out)
      out = np.array(out) # convert it to numpy

      print(out)


      numpy and ctypes versions are 1.11.1 and 1.1.0






      share|improve this answer






























        0














        If you are ok with creating arrays in python, the following example with 2d array works in python3:



        import numpy as np
        import ctypes

        OutType = (ctypes.c_float * 4) * 6
        out = OutType()
        YourCfunction = ctypes.CDLL('./yourlib.so').voidreturningfunctionwithweirdname
        YourCfunction.argtypes = [ctypes.POINTER(ctypes.c_float)]*3, ctypes.POINTER(ctypes.c_float)]*5, OutType]
        YourCfunction(input1, input2, out)
        out = np.array(out) # convert it to numpy

        print(out)


        numpy and ctypes versions are 1.11.1 and 1.1.0






        share|improve this answer




























          0












          0








          0







          If you are ok with creating arrays in python, the following example with 2d array works in python3:



          import numpy as np
          import ctypes

          OutType = (ctypes.c_float * 4) * 6
          out = OutType()
          YourCfunction = ctypes.CDLL('./yourlib.so').voidreturningfunctionwithweirdname
          YourCfunction.argtypes = [ctypes.POINTER(ctypes.c_float)]*3, ctypes.POINTER(ctypes.c_float)]*5, OutType]
          YourCfunction(input1, input2, out)
          out = np.array(out) # convert it to numpy

          print(out)


          numpy and ctypes versions are 1.11.1 and 1.1.0






          share|improve this answer















          If you are ok with creating arrays in python, the following example with 2d array works in python3:



          import numpy as np
          import ctypes

          OutType = (ctypes.c_float * 4) * 6
          out = OutType()
          YourCfunction = ctypes.CDLL('./yourlib.so').voidreturningfunctionwithweirdname
          YourCfunction.argtypes = [ctypes.POINTER(ctypes.c_float)]*3, ctypes.POINTER(ctypes.c_float)]*5, OutType]
          YourCfunction(input1, input2, out)
          out = np.array(out) # convert it to numpy

          print(out)


          numpy and ctypes versions are 1.11.1 and 1.1.0







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Aug 12 '16 at 22:28

























          answered Aug 12 '16 at 22:18









          Ilya ProkinIlya Prokin

          30729




          30729























              0














              np.ctypeslib.as_array is all you need here.



              From an array:



               c_arr = (c_float * 8)()
              np.ctypeslib.as_array(c_arr)


              From a pointer



               c_arr = (c_float * 8)()
              ptr = ctypes.pointer(c_arr[0])
              np.ctypeslib.as_array(ptr, shape=(8,))





              share|improve this answer




























                0














                np.ctypeslib.as_array is all you need here.



                From an array:



                 c_arr = (c_float * 8)()
                np.ctypeslib.as_array(c_arr)


                From a pointer



                 c_arr = (c_float * 8)()
                ptr = ctypes.pointer(c_arr[0])
                np.ctypeslib.as_array(ptr, shape=(8,))





                share|improve this answer


























                  0












                  0








                  0







                  np.ctypeslib.as_array is all you need here.



                  From an array:



                   c_arr = (c_float * 8)()
                  np.ctypeslib.as_array(c_arr)


                  From a pointer



                   c_arr = (c_float * 8)()
                  ptr = ctypes.pointer(c_arr[0])
                  np.ctypeslib.as_array(ptr, shape=(8,))





                  share|improve this answer













                  np.ctypeslib.as_array is all you need here.



                  From an array:



                   c_arr = (c_float * 8)()
                  np.ctypeslib.as_array(c_arr)


                  From a pointer



                   c_arr = (c_float * 8)()
                  ptr = ctypes.pointer(c_arr[0])
                  np.ctypeslib.as_array(ptr, shape=(8,))






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 20 '18 at 6:24









                  EricEric

                  66.8k31169279




                  66.8k31169279






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4355524%2fgetting-data-from-ctypes-array-into-numpy%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      How to pass form data using jquery Ajax to insert data in database?

                      National Museum of Racing and Hall of Fame

                      Guess what letter conforming each word