2013-10-29 3 views
2

Cython을 사용하여 유니 코드 문자열을 UCS2 형식 (wchar 배열)으로 허용하는 외부 C API와의 인터페이스로 작업하고 있습니다. (I는 UCS2 마주 UTF-16의 한계를 이해하지만, 타사 API입니다.)Cython : 유니 코드 문자열을 wchar 배열로 변환

  • 사이 썬 버전 : 0.15.1
  • 파이썬 버전 : 2.6 (좁은 유니 코드 빌드)
  • OS : FreeBSD의

바이트 문자열을 유니 코드 변환에 광범위 사이 썬 사용자 설명서 거래,하지만 난 변환하는 방법을 알아낼 수 없었다 16 비트 배열 우선 UTF-16으로 인코딩해야한다는 것을 알게되었습니다. (그리고 지금은 BMP를 넘어서는 코드 포인트가 발생하지 않는다고 가정합니다.) 다음에 무엇을해야합니까? 도와주세요.

미리 감사드립니다.

답변

0

이 파이썬 3매우 가능하며, 해결책은 다음과 같습니다

# cython: language_level=3 

from libc.stddef cimport wchar_t 

cdef extern from "Python.h": 
    wchar_t* PyUnicode_AsWideCharString(object, Py_ssize_t *) 

cdef extern from "wchar.h": 
    int wprintf(const wchar_t *, ...) 

my_string = u"Foobar\n" 
cdef Py_ssize_t length 
cdef wchar_t *my_wchars = PyUnicode_AsWideCharString(my_string, &length) 

wprintf(my_wchars) 
print("Length:", <long>length) 
print("Null End:", my_wchars[7] == 0) 

덜 좋은 파이썬이 방법은 다음하지만 정의되지 않았거나 깨진 행동에 거래 될 수있다, 그래서 좋겠 너무 쉽게 신뢰하지 않아야합니다.

# cython: language_level=2 

from cpython.ref cimport PyObject 
from libc.stddef cimport wchar_t 
from libc.stdio cimport fflush, stdout 
from libc.stdlib cimport malloc, free 

cdef extern from "Python.h": 
    ctypedef PyObject PyUnicodeObject 
    Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *o, wchar_t *w, Py_ssize_t size) 

my_string = u"Foobar\n" 
cdef Py_ssize_t length = len(my_string.encode("UTF-16")) // 2 # cheating 
cdef wchar_t *my_wchars = <wchar_t *>malloc(length * sizeof(wchar_t)) 
cdef Py_ssize_t number_written = PyUnicode_AsWideChar(<PyUnicodeObject *>my_string, my_wchars, length) 

# wprintf breaks things for some reason 
print [my_wchars[i] for i in range(length)] 
print "Length:", <long>length 
print "Number Written:", <long>number_written 
print "Null End:", my_wchars[7] == 0 

free(my_wchars)