Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Python's <code>PyIntObject</code> uses a C <code>long</code> internally, which is 64-bit on most 64-bit platforms (excluding 64-bit Windows). However, ctypes assigns the converted result to <code>pa-&gt;value.i</code>, where <code>value</code> is a union and the <code>i</code> field is a 32-bit <code>int</code>. For the details, see <code>ConvParam</code> in <a href="http://hg.python.org/cpython/file/ab05e7dd2788/Modules/_ctypes/callproc.c#l559" rel="noreferrer">Modules/_ctypes/callproc.c</a>, lines 588-607 and 645-664. ctypes was developed on Windows, where a <code>long</code> is always 32-bit, but I don't know why this hasn't been changed to use the <code>long</code> field instead, i.e. <code>pa-&gt;value.l</code>. Probably, it's just more convenient most of the time to default to creating a C <code>int</code> instead of using the full range of the <code>long</code>.</p> <p>Anyway, this means you can't simply pass a Python <code>int</code> to create a 64-bit pointer. You have to explicitly create a ctypes pointer. You have a number of options for this. If you're not concerned about type safety, the simplest option for a NumPy array is to use its <code>ctypes</code> attribute. This defines the hook <code>_as_parameter_</code> that lets Python objects set how they're converted in ctypes function calls (see lines 707-719 in the previous link). In this case it creates a <code>void *</code>. For example, you'd call <code>plate</code> like this:</p> <pre><code>plate.plate(x.ctypes, y.ctypes, N) </code></pre> <p>However, this doesn't offer any type safety to prevent the function from being called with an array of the wrong type, which will result in either nonsense, bugs, or a segmentation fault. <a href="http://docs.scipy.org/doc/numpy/reference/routines.ctypeslib.html#numpy.ctypeslib.ndpointer" rel="noreferrer"><code>np.ctypeslib.ndpointer</code></a> solves this problem. This creates a custom type that you can use in setting the <code>argtypes</code> and <code>restype</code> of a ctypes function pointer. This type can verify the array's data type, number of dimensions, shape, and flags. For example:</p> <pre><code>import numpy as np import ctypes c_npfloat32_1 = np.ctypeslib.ndpointer( dtype=np.float32, ndim=1, flags=['C', 'W']) plate = ctypes.CDLL('libplate.so') plate.plate.argtypes = [ c_npfloat32_1, c_npfloat32_1, ctypes.c_int, ] N = 3 x = np.ones(N, dtype=np.float32) y = np.ones(N, dtype=np.float32) plate.plate(x, y, N) # the parameter is the array itself </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload