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.

3
  • If w and h are inputs, why are they declared int *? Commented Feb 19, 2019 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. Commented Feb 25, 2019 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. Commented Feb 25, 2019 at 19:19

1 Answer 1

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.
Sign up to request clarification or add additional context in comments.

2 Comments

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!
Good to hear that! Please let other people know, by marking the answer as a solution to your question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.