0% found this document useful (0 votes)
3 views

The create_string_buffer()

The document discusses the use of the create_string_buffer() and create_unicode_buffer() functions in ctypes for creating mutable memory blocks. It explains how to call C functions from Python, including the need to wrap Python types in ctypes types and customize argument conversion for custom classes. Additionally, it covers specifying argument and return types for functions exported from DLLs to ensure compatibility and proper conversion.

Uploaded by

diegohazael2005
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

The create_string_buffer()

The document discusses the use of the create_string_buffer() and create_unicode_buffer() functions in ctypes for creating mutable memory blocks. It explains how to call C functions from Python, including the need to wrap Python types in ctypes types and customize argument conversion for custom classes. Additionally, it covers specifying argument and return types for functions exported from DLLs to ensure compatibility and proper conversion.

Uploaded by

diegohazael2005
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

The create_string_buffer() function replaces the c_buffer() function (which

is still available as an alias), as well as the c_string() function from earlier ctypes
releases. To create a mutable memory block containing unicode characters of the C
type wchar_t use the create_unicode_buffer() function.

Calling functions, continued

Note that printf prints to the real standard output channel, not to sys.stdout, so
these examples will only work at the console prompt, not from within IDLE or
PythonWin:

>>>

>>> printf = libc.printf

>>> printf(b"Hello, %s\n", b"World!")

Hello, World!

14

>>> printf(b"Hello, %S\n", "World!")

Hello, World!

14

>>> printf(b"%d bottles of beer\n", 42)

42 bottles of beer

19

>>> printf(b"%f bottles of beer\n", 42.5)

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

ArgumentError: argument 2: exceptions.TypeError: Don't know how to


convert parameter 2
>>>

As has been mentioned before, all Python types except integers, strings, and bytes
objects have to be wrapped in their corresponding ctypes type, so that they can be
converted to the required C data type:

>>>

>>> printf(b"An int %d, a double %f\n", 1234, c_double(3.14))

An int 1234, a double 3.140000

31

>>>

Calling functions with your own custom data types

You can also customize ctypes argument conversion to allow instances of your own
classes be used as function arguments. ctypes looks for an _as_parameter_
attribute and uses this as the function argument. Of course, it must be one of integer,
string, or bytes:

>>>

>>> class Bottles:

... def __init__(self, number):

... self._as_parameter_ = number

...

>>> bottles = Bottles(42)

>>> printf(b"%d bottles of beer\n", bottles)

42 bottles of beer
19

>>>

If you don’t want to store the instance’s data in the _as_parameter_ instance
variable, you could define a property which makes the attribute available on
request.

Specifying the required argument types (function


prototypes)

It is possible to specify the required argument types of functions exported from DLLs
by setting the argtypes attribute.

argtypes must be a sequence of C data types (the printf function is probably not
a good example here, because it takes a variable number and different types of
parameters depending on the format string, on the other hand this is quite handy to
experiment with this feature):

>>>

>>> printf.argtypes = [c_char_p, c_char_p, c_int, c_double]

>>> printf(b"String '%s', Int %d, Double %f\n", b"Hi", 10, 2.2)

String 'Hi', Int 10, Double 2.200000

37

>>>

Specifying a format protects against incompatible argument types (just as a


prototype for a C function), and tries to convert the arguments to valid types:

>>>

>>> printf(b"%d %d %d", 1, 2, 3)


Traceback (most recent call last):

File "<stdin>", line 1, in <module>

ArgumentError: argument 2: exceptions.TypeError: wrong type

>>> printf(b"%s %d %f\n", b"X", 2, 3)

X 2 3.000000

13

>>>

If you have defined your own classes which you pass to function calls, you have to
implement a from_param() class method for them to be able to use them in the
argtypes sequence. The from_param() class method receives the Python object
passed to the function call, it should do a typecheck or whatever is needed to make
sure this object is acceptable, and then return the object itself, its _as_parameter_
attribute, or whatever you want to pass as the C function argument in this case.
Again, the result should be an integer, string, bytes, a ctypes instance, or an object
with an _as_parameter_ attribute.

Return types

By default functions are assumed to return the C int type. Other return types can be
specified by setting the restype attribute of the function object.

Here is a more advanced example, it uses the strchr function, which expects a
string pointer and a char, and returns a pointer to a string:

You might also like