homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: ctypes feature request: Automatic type conversion of input arguments to C functions
Type: enhancement Stage:
Components: Extension Modules Versions: Python 3.2
process
Status: closed Resolution: works for me
Dependencies: Superseder:
Assigned To: theller Nosy List: amaury.forgeotdarc, christian.heimes, mattbaas, theller
Priority: normal Keywords:

Created on 2008年01月29日 08:59 by mattbaas, last changed 2022年04月11日 14:56 by admin. This issue is now closed.

Messages (4)
msg61815 - (view) Author: (mattbaas) Date: 2008年01月29日 08:59
This is rather a feature request instead of a bug report. 
Below is the mail I posted to the ctypes-users mailing list. In short: 
When ctypes checks input argument types using the "argtypes" attribute, 
it would be useful if it would try to convert the input value 
automatically if it isn't already an appropriate ctypes type (but a 
"compatible" Python type).
Here is the full mail with some examples:
I'm wrapping a couple of C functions from a DLL and I'm using the 
argtypes attribute to declare the types of the input arguments. I can 
call the functions just fine, but I was wondering why I have to provide 
the exact ctypes type as input when using more complex types such as 
arrays or callbacks (whereas Python floats are automatically converted).
Here is an example code snippet (I was using Python 2.5 on WinXP). The 
library ri.dll contains the functions RiColor() which takes an array of 
3 floats as input and a function RiErrorHandler() which takes a pointer 
to a function as input:
 # Create the required types...
 RtColor = 3*c_float
 RtErrorHandler = CFUNCTYPE(None, c_int, c_int, c_char_p)
 # Load the library and declare the input arguments...
 ri = cdll.LoadLibrary("ri.dll")
 ri.RiColor.argtypes = [RtColor]
 ri.RiErrorHandler.argtypes = [RtErrorHandler]
Now I can call the color function like this:
 ri.RiColor(RtColor(1,0,0))
But sometimes it would be more convenient to work with other types like 
tuples, lists or, in this case, a special vector type (that may come 
from another module but that behaves like a list of 3 floats).
But when I try to pass in just a Python tuple or list I get the 
following errors:
 ri.RiColor((1,0,0))
 --> ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: 
Don't know how to convert parameter 1
 ri.RiColor([1,0,0])
 --> ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: 
expected c_float_Array_3 instance instead of list
Similarly with the error handler function. I have to wrap a Python 
function with the RtErrorHandler type, otherwise ctypes won't accept it:
 def errHandler(code, severity, message):
 pass
 ri.RiErrorHandler(RtErrorHandler(errHandler)) # works
 ri.RiErrorHandler(errHandler) # produces a TypeError
So whenever an input type doesn't match what was specified in argtypes, 
couldn't ctypes try to convert the value before issuing an error? (it 
works with floats, so why not with other types as well?)
The conversion could just be done by passing the value to the 
constructor of the required type. In the color example this also means 
that array types should also accept sequences as input (i.e. anything 
that supports iteration and has the right number of elements).
I think this modification to ctypes would make the wrapped functions 
more flexible without having to write additional wrapper functions in 
Python.
msg61819 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2008年01月29日 14:23
Feature request -> RFE (request for enhancement)
msg116939 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2010年09月20日 14:08
Is this ever likely to happen, given that there's been 2.75 years since the request without a response?
msg117087 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2010年09月21日 17:56
I don't think this should happen by default.
but what the user wants is already possible, by using the from_param() method. For example, the AutoStrParam type converts everything to a string (and a char*):
from ctypes import *
class AutoStrParam(c_char_p):
 @classmethod
 def from_param(cls, value):
 return str(value)
strlen = cdll.LoadLibrary('msvcrt').strlen
strlen.argtypes = [AutoStrParam]
print strlen(None) # "None" -> 4
print strlen(type) # "<type 'type'>" -> 13
History
Date User Action Args
2022年04月11日 14:56:30adminsetgithub: 46254
2014年11月24日 16:07:00amaury.forgeotdarcsetstatus: open -> closed
resolution: works for me
2010年09月21日 22:24:46amaury.forgeotdarcsetmessages: - msg117111
2010年09月21日 22:16:58amaury.forgeotdarcsetnosy: - BreamoreBoy
2010年09月21日 22:16:51amaury.forgeotdarcsetfiles: - unnamed
2010年09月21日 21:58:51BreamoreBoysetfiles: + unnamed

messages: + msg117111
2010年09月21日 17:56:49amaury.forgeotdarcsetnosy: + amaury.forgeotdarc
messages: + msg117087
2010年09月20日 14:08:11BreamoreBoysetnosy: + BreamoreBoy
messages: + msg116939
2010年07月10日 05:33:37terry.reedysetversions: + Python 3.2, - Python 2.6
2008年01月29日 14:23:10christian.heimessetversions: + Python 2.6, - Python 2.5
nosy: + christian.heimes, theller
messages: + msg61819
priority: normal
assignee: theller
type: behavior -> enhancement
2008年01月29日 08:59:40mattbaascreate

AltStyle によって変換されたページ (->オリジナル) /