Commit 46b39552 authored by scoder's avatar scoder Committed by GitHub

Merge pull request #2361 from gabrieldemarmiesse/test_string

Extended the examples of string.rst and put them in the examples directory for testing.
parents 59f33a96 5656dea4
cdef char* c_call_returning_a_c_string()
cdef void get_a_c_string(char** c_string, Py_ssize_t *length)
from libc.stdlib cimport malloc
from libc.string cimport strcpy, strlen
cdef char* hello_world = 'hello world'
cdef Py_ssize_t n = strlen(hello_world)
cdef char* c_call_returning_a_c_string():
cdef char* c_string = <char *> malloc((n + 1) * sizeof(char))
if not c_string:
raise MemoryError()
strcpy(c_string, hello_world)
return c_string
cdef void get_a_c_string(char** c_string_ptr, Py_ssize_t *length):
c_string_ptr[0] = <char *> malloc((n + 1) * sizeof(char))
if not c_string_ptr[0]:
raise MemoryError()
strcpy(c_string_ptr[0], hello_world)
length[0] = n
from libc.stdlib cimport free
from c_func cimport get_a_c_string
def main():
cdef char* c_string = NULL
cdef Py_ssize_t length = 0
# get pointer and length from a C function
get_a_c_string(&c_string, &length)
try:
py_bytes_string = c_string[:length] # Performs a copy of the data
finally:
free(c_string)
...@@ -107,11 +107,22 @@ within a well defined context. ...@@ -107,11 +107,22 @@ within a well defined context.
Passing byte strings Passing byte strings
-------------------- --------------------
we have dummy C functions declared in
a file called :file:`c_func.pyx` that we are going to reuse throughout this tutorial:
.. literalinclude:: ../../examples/tutorial/string/c_func.pyx
We make a corresponding :file:`c_func.pxd` to be able to cimport those functions:
.. literalinclude:: ../../examples/tutorial/string/c_func.pxd
It is very easy to pass byte strings between C code and Python. It is very easy to pass byte strings between C code and Python.
When receiving a byte string from a C library, you can let Cython When receiving a byte string from a C library, you can let Cython
convert it into a Python byte string by simply assigning it to a convert it into a Python byte string by simply assigning it to a
Python variable:: Python variable::
from c_func cimport c_call_returning_a_c_string
cdef char* c_string = c_call_returning_a_c_string() cdef char* c_string = c_call_returning_a_c_string()
cdef bytes py_string = c_string cdef bytes py_string = c_string
...@@ -133,15 +144,9 @@ C string first to find out the length by counting the bytes up to the ...@@ -133,15 +144,9 @@ C string first to find out the length by counting the bytes up to the
terminating null byte. In many cases, the user code will know the terminating null byte. In many cases, the user code will know the
length already, e.g. because a C function returned it. In this case, length already, e.g. because a C function returned it. In this case,
it is much more efficient to tell Cython the exact number of bytes by it is much more efficient to tell Cython the exact number of bytes by
slicing the C string:: slicing the C string. Here is an example:
cdef char* c_string = NULL
cdef Py_ssize_t length = 0
# get pointer and length from a C function
get_a_c_string(&c_string, &length)
py_bytes_string = c_string[:length] .. literalinclude:: ../../examples/tutorial/string/slicing_c_string.pyx
Here, no additional byte counting is required and ``length`` bytes from Here, no additional byte counting is required and ``length`` bytes from
the ``c_string`` will be copied into the Python bytes object, including the ``c_string`` will be copied into the Python bytes object, including
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment