You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
By clicking “Sign up for GitHub”, you agree to our
terms of service
and
privacy statement
. We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
Bug description:
When the array starts with \x00:
from ctypes import create_string_buffer, c_char, addressof
bs = b"\x00\x01\x02\x03\x04"
s = create_string_buffer(bs)
array = (c_char * 16).from_address(addressof(s))
print(array.value)
CPython versions tested on:
Operating systems tested on:
Linux
What result do you expect?
In C language, an array of chars starting with
'\x00'
always returns
''
. The instruction
(c_char * 16)
creates a 16-character C array, then initialized with a copy of your
bs
variable, where the first byte is
'\x00'
.
Return value
b''
is correct.
What result do you expect?
In C language, an array of chars starting with
'\x00'
always returns
''
. The instruction
(c_char * 16)
creates a 16-character C array, then initialized with a copy of your
bs
variable, where the first byte is
'\x00'
.
Return value
b''
is correct.
It's representation detail that "strings" are nul-terminated (you are
treating
array of chars as a string where it is supposed to be string), actually array of
char
s are not necessarily strings, but some opaque byte buffers, so expected output is
bytes
of length 16.
What result do you expect?
In C language, an array of chars starting with
'\x00'
always returns
''
. The instruction
(c_char * 16)
creates a 16-character C array, then initialized with a copy of your
bs
variable, where the first byte is
'\x00'
.
Return value
b''
is correct.
It's representation detail that "strings" are nul-terminated (you are
treating
array of chars as a string where it is supposed to be string), actually array of
char
s are not necessarily strings, but some opaque byte buffers, so expected output is
bytes
of length 16.
Ah, this is not valid, since example code contains
create_string_buffer
, so interpreting these bytes as a string is a right thing to do, but related
#117822
looks like a bug
Due to the semantics of
create_string_buffer
, interpreting these bytes as string is right thing to do.
So, there's no bug.
Another case which is related to this problem is
#117822
where
create_string_buffer
isn't used, so the semantics of strings cannot be applied there (but it actually does).
As it is sort of documented in the
fundamental data types
section of the ctypes tutorial, a
c_char
array, unlike other
Array
subclasses, has a
value
property and a
raw
property. The
value
property is the value of the character array as a null-terminated string. You want the
raw
property, or a slice. For example:
>>> bs = b"\x00\x01\x02\x03\x04"
>>> s = ctypes.create_string_buffer(bs, size=len(bs))
>>> s.raw
b'\x00\x01\x02\x03\x04'
b'\x00\x01\x02\x03\x04'
For some reason
c_wchar
arrays have a
value
as a null-terminated string but no
raw
property. I think this is an oversight in the design. For example:
>>> s = "\x00\x01\x02\x03\x04"
>>> a = ctypes.create_unicode_buffer(s, size=len(s))
>>> hasattr(a, 'raw')
False
'\x00\x01\x02\x03\x04'
>>> a.value
It's also a long-standing issue that the documentation of ctypes is severely lacking. The tutorial needs to be moved to a separate page, and the actual reference documentation needs to be extended a lot.
BTW, (c_char * 16).from_address(addressof(s))
might crash the current process. The s
array that you created has 6 bytes allocated. Attempting to access 10 bytes beyond that might segfault (access violation on Windows) if that address range isn't allocated. In this case it likely is because the array would be allocated from the heap, but larger allocations get allocated via mmap()
(or VirtualAlloc()
on Windows) outside of the heap.