Reputation: 61
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.
Upvotes: 5
Views: 13370
Reputation: 10906
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)
.
Upvotes: 8