14.14.1.4 Fundamental data types

###
14.14.1.4 Fundamental data types

`ctypes` defines a number of primitive C compatible data types :

ctypes type | C type | Python type
--- | --- | ---
`c_char` | `char` | 1-character string
`c_wchar` | `wchar_t` | 1-character unicode string
`c_byte` | `char` | int/long
`c_ubyte` | `unsigned char` | int/long
`c_short` | `short` | int/long
`c_ushort` | `unsigned short` | int/long
`c_int` | `int` | int/long
`c_uint` | `unsigned int` | int/long
`c_long` | `long` | int/long
`c_ulong` | `unsigned long` | int/long
`c_longlong` | `__int64` or `long long` | int/long
`c_ulonglong` | `unsigned __int64` or `unsigned long long` | int/long
`c_float` | `float` | float
`c_double` | `double` | float
`c_char_p` | `char *` (NUL terminated) | string or `None`
`c_wchar_p` | `wchar_t *` (NUL terminated) | unicode or `None`
`c_void_p` | `void *` | int/long or `None`

All these types can be created by calling them with an optional initializer of the correct type and value:

    >>> c_int()
    c_long(0)
    >>> c_char_p("Hello, World")
    c_char_p('Hello, World')
    >>> c_ushort(-3)
    c_ushort(65533)
    >>>

Since these types are mutable, their value can also be changed afterwards:

    >>> i = c_int(42)
    >>> print i
    c_long(42)
    >>> print i.value
    42
    >>> i.value = -99
    >>> print i.value
    -99
    >>>

Assigning a new value to instances of the pointer types `c_char_p`, `c_wchar_p`, and `c_void_p` changes the memory location they point to, not the contents of the memory block (of course not, because Python strings are immutable):

    >>> s = "Hello, World"
    >>> c_s = c_char_p(s)
    >>> print c_s
    c_char_p('Hello, World')
    >>> c_s.value = "Hi, there"
    >>> print c_s
    c_char_p('Hi, there')
    >>> print s                 # first string is unchanged
    Hello, World
    >>>

You should be careful, however, not to pass them to functions expecting pointers to mutable memory. If you need mutable memory blocks, ctypes has a `create_string_buffer` function which creates these in various ways. The current memory block contents can be accessed (or changed) with the `raw` property; if you want to access it as NUL terminated string, use the `value` property:

    >>> from ctypes import *
    >>> p = create_string_buffer(3)      # create a 3 byte buffer, initialized to NUL bytes
    >>> print sizeof(p), repr(p.raw)
    3 '\x00\x00\x00'
    >>> p = create_string_buffer("Hello")      # create a buffer containing a NUL terminated string
    >>> print sizeof(p), repr(p.raw)
    6 'Hello\x00'
    >>> print repr(p.value)
    'Hello'
    >>> p = create_string_buffer("Hello", 10)  # create a 10 byte buffer
    >>> print sizeof(p), repr(p.raw)
    10 'Hello\x00\x00\x00\x00\x00'
    >>> p.value = "Hi"
    >>> print sizeof(p), repr(p.raw)
    10 'Hi\x00lo\x00\x00\x00\x00\x00'
    >>>

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.