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.

too honest for this site
12.3k4 gold badges33 silver badges53 bronze badges
asked Jul 6, 2017 at 22:57

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).

answered Jul 6, 2017 at 23:26
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

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.