2

I'm new to C integration in Python. I'm currently wrapping a .dll library into my Python code using ctypes and I'm having issues passing a pointer to save the output of a particular function.

My C function has the following structure:

function (int* w, int* h, unsigned short* data_output)

Where h and w are inputs and data_output is an array of size (w x h, 1).

I was able to successfully integrate and retrieve results from the function in Matlab by creating a zeros(w x h,1) array and passing it as a pointer using libpointer('uint16Ptr', zeros(w x h, 1)).

How can I do that in Python?

For other functions, where the output was of int* type I was able to successfully retrieve the values using create_string_buffer. But I haven't managed to make it work for this one.

Thank you.

JRab
  • 23
  • 3
  • If `w` and `h` are inputs, why are they declared `int *`? – Mark Tolonen Feb 19 '19 at 18:05
  • @MarkTolonen: From what I've learned so far, because the inputs are pointers to the variables `w` and `h`, which are of `int` type. – JRab Feb 25 '19 at 17:58
  • You don't need pointers to variables for inputs. `function(int w, int h, unsigned short* data_output)` would be easier to use. The answer below didn't use them for that reason. – Mark Tolonen Feb 25 '19 at 19:19

1 Answers1

3

According to [SO]: How to create a Minimal, Complete, and Verifiable example (mcve), your question doesn't contain basic info (e.g. your attempts). Make sure to correct that in the next ones.

Also, [Python.Docs]: ctypes - A foreign function library for Python.

Here's a dummy example that illustrates the concept.

dll00.c:

#include <stddef.h>

#if defined(_WIN32)
#  define DLL_EXPORT __declspec(dllexport)
#else
#  define DLL_EXPORT
#endif


DLL_EXPORT int function(int w, int h, unsigned short *pData)
{
    if (pData == NULL) {
        return -1;
    }
    int k = 0;
    for (int i = 0; i < h; ++i)
        for (int j = 0; j < w; ++j)
            pData[i * w + j] = ++k;
    return w * h;
}

code00.py:

#!/usr/bin/env python

import ctypes as cts
import sys


DLL_NAME = "./dll00.{:s}".format("dll" if sys.platform[:3].lower() == "win" else "so")


def print_array(data, h, w):
    for i in range(h):
        for j in range(w):
            print("{:2d}".format(data[i * w + j]), end=" ")
    print()


def main(*argv):
    dll_dll = cts.CDLL(DLL_NAME)
    function = dll_dll.function
    function.argtypes = (cts.c_int, cts.c_int, cts.POINTER(cts.c_ushort))
    function.restype = cts.c_int

    h = 3
    w = 5

    ArrayType = cts.c_ushort * (h * w)  # Dynamically declare the array TYPE: `unsigned short[15]` in our case
    array = ArrayType()  # The array type INSTANCE

    print_array(array, h, w)
    res = function(w, h, cts.cast(array, cts.POINTER(cts.c_ushort)))
    print("{:} returned: {:d}".format(function.__name__, res))

    print_array(array, h, w)


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.\n")
    sys.exit(rc)

Output:

(qaic-env) [cfati@cfati-5510-0:/mnt/e/Work/Dev/StackExchange/StackOverflow/q054753828]> ~/sopr.sh
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###

[064bit prompt]> ls
code00.py  dll00.c
[064bit prompt]> gcc -fPIC -shared -o dll00.so dll00.c
[064bit prompt]> ls
code00.py  dll00.c  dll00.so
[064bit prompt]> 
[064bit prompt]> python ./code00.py 
Python 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0] 064bit on linux

 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
function returned: 15
 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 

Done.
CristiFati
  • 38,250
  • 9
  • 50
  • 87
  • Dear Cristi. Thank you for the recommendations on the question formulation and response. I was able to successfully implement the library using your dummy example. Best regards! – JRab Feb 25 '19 at 17:52
  • Good to hear that! Please let other people know, by marking the answer as a solution to your question. – CristiFati Feb 25 '19 at 19:38