5

I am trying to call functions from a C library in python 2.7. I am rather confused by most tutorials or information I've found so far.

The C function takes in 3 doubles (labeled h, k, l) and 2 pointers to a double (*p, *q) to iteratively solve the two doubles, initialized with 0.0 for simplicity. The function returns nothing, it just uses the pointers to modify the values of p and q.

My current code reads:

import ctypes
path = '/foo/bar.so'
_lib = ctypes.CDLL(path)
_lib.solve.argtypes = (ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double))

def py_solve(h, k, l):
    global _lib
    p, q = ctypes.c_double(0.0), ctypes.c_double(0.0)
    _lib.solve(ctypes.c_double(h), ctypes.c_double(k), ctypes.c_double(l), ctypes.POINTER(p), ctypes.POINTER(q))
    return float(p), float(q)

I get:

'TypeError: must be a ctypes type'

on the line calling _lib.solve(...) in my py_solve function. Maybe this would be simpler by using ctypes' byref() function but I am unsure how to do that as well. Any help is appreciated, thanks.

1 Answer 1

8

The function ctypes.POINTER takes an argument that is a ctypes type. When you use it in the line

_lib.solve.argtypes = (ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double))

that's exactly what you're doing, since ctypes.c_double is a type.

When later you call it like this:

ctypes.POINTER(p)

the argument isn't a type but an instance of a type - an already initialized variable of type ctypes.c_double.

All you need to do is to create a pointer to the already initialized variables p and q. Just replace ctypes.POINTER(p) with ctypes.byref(p).

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. Very well explained, things make sense now.
Note that byref doesn't create a ctypes pointer per se, unlike ctypes.pointer or instantiating a pointer type. byref directly references the buffer of a ctypes object, which is more efficient than creating a ctypes pointer.
See also this documentation section on this very point.

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.