2015-08-19 3 views
0

У меня есть программа, которая символизирует тайский текст, вызывающий библиотеку libtahi C. Эти программы работают нормально с python 3.2, но не с python3.4. Любая идея, почему это не удается на 3,4?Программа python ctypes работает на 3.2, но несовместима на 3.4

Вы найдете ниже программный код и выводит как с версией Python:

#!/usr/bin/python3 
# apt-get install libthai0 libthai-doc libthai-dev libthai-data 
from ctypes import * 
from ctypes.util import find_library 

THAI_LIBRARY = find_library('thai') 
if not THAI_LIBRARY: 
    raise OSError('Cannot find libthai in the system') 

thai = cdll.LoadLibrary(THAI_LIBRARY) 

thai.th_wbrk_line.restype = c_int 
thai.th_wbrk_line.argtypes = [c_wchar_p,c_wchar_p,c_size_t,c_wchar_p] 

def whitespace(ain): 
    # expects bytes 
    ain=ain.decode('utf8') 
    aout=whitespace_string(ain) 
    return aout.encode('utf8') 

def whitespace_string(ain): 
    # expects a string 
    # ain='แล้วพบกันใหม่' 
    aout=' '*(2*len(ain)+1) 
    # we assume that the maximum length is a set of one character + white space 
    adelim=' ' 
    asize=len(aout) 
    res=thai.th_wbrk_line(ain,aout,asize,adelim) 
    result=aout[:res] 
    return result 

""" 
แล้วพบกันใหม่ means 'See you later.' 

and is compound by three words: 

แล้ว 
พบกัน 
ใหม่ 
""" 


if __name__ == "__main__": 

    ain='แล้วพบกันใหม่' 
    aout=whitespace_string(ain) 
    print(ain,'=>',aout) 
    aout=whitespace(ain.encode('utf8')) 
    print(aout.decode('utf8')) 

Выходы: с python3.2 токенизации происходит:

python3.2 thai_libthai.py 
แล้วพบกันใหม่ => แล้ว พบ กัน ใหม่ 
แล้ว พบ กัน ใหม่ 

с python3.4 результатом строка не заполнена:

python3.4 thai_libthai.py 
แล้วพบกันใหม่ =>     
+0

Вы не можете передать строку Python в качестве выходного буфера. Используйте 'aout = (c_wchar * (2 * len (ain) + 1))()' или 'aout = create_unicode_buffer (2 * len (ain) + 1)'. – eryksun

+0

В этом случае он работает в Python 3.2, потому что ctypes использует макрос 'PyUnicode_AS_UNICODE', чтобы напрямую передать базовый буфер' wchar_t * ', используемый объектом. Это невозможно использовать в 3.3+, поскольку базовое строковое представление было [полностью изменено] (https://www.python.org/dev/peps/pep-0393). Теперь он вызывает 'PyUnicode_AsWideCharString' для создания временного буфера' wchar_t', который поддерживается для вызова, ссылаясь на 'capsule' во временном' CArgObject'. – eryksun

+0

3.4.3 ссылки источника: ['c_wchar_p_from_param'] (https://hg.python.org/cpython/file/v3.4.3/Modules/_ctypes/_ctypes.c#l1470) и [' Z_set'] (https: //hg.python.org/cpython/file/v3.4.3/Modules/_ctypes/cfield.c#l1374). – eryksun

ответ

0

Использование aout = (c_wchar * (2 * len(ain) + 1))() делает код работающим как на python 3.2, так и на 3.4. Спасибо, eryksun!