2016-07-26 14 views
1

下面的Cython代碼不能按預期工作。Cython中的空字符問題

cdef char* char_tester(): 
    py_str = "a\0b\0c".encode("UTF-8") 
    cdef char* c_str = py_str 
    return c_str 

def test(): 
    print(char_tester()) 
    cdef char* my_str = char_tester() 
    for i in range(5): 
     print(my_str[i]) 

>>> test() 
b'a' 
97 
55 
10 
0 
99 

我期望的代碼要被打印出的字節串 'A B C',和ASCII值97,0,98,0,99,以該順序。此外,當我添加for循環打印for循環內的字符時,我得到預期的ASCII值作爲輸出。顯然,由char_tester返回的char*正在以某種方式在test()函數中被截斷。我如何防止這種情況發生,並獲得預期的輸出?

+0

你看看[文件](http://docs.cython.org/en /latest/src/tutorial/strings.html)?我假設從Python函數調用C函數會將'char *'轉換爲Python字符串,並將其視爲以空字符結尾的字符串。 – BrenBarn

+0

是的,但我在行中指定了變量的類型: cdef char * my_str = char_tester(),所以這應該是不相關的。 – Alex

回答

2

Assigment cdef char * s = py_str指向char_tester()返回後無效的內存位置。就像C函數將地址返回給本地堆棧分配的變量,未定義的行爲一樣。

用下面的函數

from libc.stdlib cimport malloc 
from libc.string cimport memcpy 

cdef char* char_tester(): 
    py_str = "a\0b\0c".encode("UTF-8") 
    cdef char* c_str 
    cdef char * s = py_str 
    cdef ssize_t slen = len(py_str) 

    c_str = <char *>malloc((slen+1)*sizeof(char)) 
    memcpy(c_str, s, slen) 
    c_str[slen] = '\0' 
    return c_str 

測試代碼將打印(蟒蛇3.4)

b'a' 
97 
0 
98 
0 
99 
+0

由於已經有'\ 0',所以在這種情況下可能不需要char數組末尾的額外'\ 0'。 –