2

Is it possible to automatically convert a Python int to a ctypes integer pointer using the argtypes attribute?

E.G.

import ctypes cfunc = ctypes.CDLL('somelib.so').somefunc i = 100 cfunc.argtypes = [ctypes.POINTER(ctypes.c_int)] cfunc(i) 

I was hoping that the argtypes attribute could be used to automatically convert the python integer...but I get an error

<type 'exceptions.TypeError'>: expected LP_c_int instance instead of int 

I assume it is because the argtype is actually made up of two ctypes calls?

Obviously, this works:

cfunc(ctypes.byref(ctypes.c_int(i))) 

but is a bit verbose, especially with multiple arguemnts!

1
  • from ctypes import c_int, byref, etc makes the line considerably shorter. :) from ctypes import by_ref as R even more. Commented Nov 12, 2018 at 15:28

1 Answer 1

3

There is no automatic conversion to a pointer type.

POINTER(c_int) is a pointer to a C integer, implying storage, and typically implying it is an output parameter. Where would the output value go if you had called somefunc(7)?

Obviously, this works:

cfunc(ctypes.byref(ctypes.c_int(i)))

Not so obviously, if that C int* is written to, you've created a temporary C int storage value. If cfunc writes to that storage, it is immediately freed after the function returns and there is no way to access the value. So you have to create storage and assign it to a variable to maintain the reference long enough to retrieve the value:

v = ctypes.c_int(100) # Create C int storage for Python int 100. cfunc(ctypes.byref(v)) # Pass 100 by reference into the function print(v.value) # Retrieve the returned C int as a Python int. 
Sign up to request clarification or add additional context in comments.

1 Comment

Good point regarding my "obviously" comment...I came to a similar conclusion earlier!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.