2015-10-07 4 views
-1

Я пытаюсь использовать для вызова функции C из файла .so от Python 3.4. Я внедрил некоторые необходимые изменения, чтобы код Python 2.7 работал с Python 3.4, но я все еще работаю в Fatal Python error: Segmentation fault.Портирование кода Python 2.7, вызывающего функцию C на Python 3.4

Код Bitbucket hosted project. Я установил его через pip3 (pip3 install Lemmagen), который также создал файл .so, который я пытаюсь использовать с Python3.

Вот исходный код Python2.7 (функция, где происходит вызов кода C), который отлично работает с python из командной строки.

def lemmatize(self, word): 
    if (self._output_buffer_len < 2 * len(word)): 
     self._output_buffer_len = 2 * len(word) 
     self._output_buffer = create_string_buffer(self._output_buffer_len) 

    is_unicode = isinstance(word, unicode) 
    if is_unicode: 
     word = word.encode('utf-8') 

    self._lib.lem_lemmatize_word(word, self._output_buffer) 
    return self._output_buffer.value.decode('utf-8') if is_unicode else self._output_buffer.value 

И это, как я пытаюсь адаптировать его к Python3.4:

def lemmatize(self, word): 
    if (self._output_buffer_len < 2 * len(word)): 
     self._output_buffer_len = 2 * len(word) 
     self._output_buffer = create_string_buffer(self._output_buffer_len) 

    word = word.encode('utf-8') 


    self._lib.lem_lemmatize_word(word, self._output_buffer) #SEGFAULT HERE! 
    #return "HERE" 
    return self._output_buffer.value.decode('utf-8') 

Я извлекал строки, которые проверяют ли word является unicode или нет, так как Unicode по умолчанию в Python3. Икс. Я все еще на 80% уверен, что это проблема с кодировкой символов . Какую кодировку я должен использовать для передать строковую переменную вызову функцииself._lib.lem_lemmatize_word(word, self._output_buffer)? Это точная линия, где происходит ошибка сегментации:

Fatal Python ошибка: ошибка сегментирования

Current thread 0xb754b700 (most recent call first): 
    File "/usr/local/lib/python3.4/dist-packages/lemmagen/lemmatizer.py", line 66 in lemmatize 
    File "<stdin>", line 1 in <module> 
Segmentation fault (core dumped) 

Я пытался читать на мой точный вопрос (тип кодирования), но я ничего не нашел, так похоже, это решает. Буду признателен за продуманную информацию об этом. Спасибо.

Спасибо за то, что кто-то запустил вопрос без причины или комментариев.

+0

Возможно, стоит добавить, что вы используете ctypes, поэтому вы вызываете функцию C, а не функцию C++. – Pim

+0

Хорошо, я исправлю это. –

+0

@Pim @DrunkenMaster 'lem_lemmatize_word' на самом деле определяется как' extern 'C "в источниках, поэтому вызов его через ctypes не должен быть проблемой. – Vovanrock2002

ответ

2

Чтобы создать массив символов, вам необходимо использовать функцию create_string_buffer, прежде чем передавать его функции.

Что-то, как это должно работать:

import ctypes 

class Lib: 
    def __init__(self): 
     self.lib = ctypes.cdll.LoadLibrary('/home/pim/slovene_lemmatizer/bin/libLemmatizer.so') 


def lemmatize(self, word): 
    text = "text" 
    output_buffer = ctypes.create_string_buffer(text.encode()) 

    word_buffer = ctypes.create_string_buffer(word.encode()) 

    self.lib.lem_lemmatize_word(word, output_buffer) 

    print("test") 

def main(): 
    lib = Lib() 
    lib.lemmatize("test") 


if __name__ == '__main__': 
    main() 

это выходы:

[email protected]:~/slovene_lemmatizer/bin$ python3 main.py [ERROR] Language file for lemmatizer has to be loaded first! test [email protected]:~/slovene_lemmatizer/bin$

Edit: Я не 100% уверен, является ли использование в 'сырой' собственности здесь правильно хотя, но это работает! Edit2: Он работает без сырого свойства, обновляется awnser

+0

Я не уверен в этом, эта модификация дает мне объект AttributeError: 'bytes' не имеет атрибута 'raw'' для последней строки кода в вашем фрагменте. –

+0

Мой плохой я обновил awnser – Pim

+0

Спасибо, это была только опечатка, теперь я ее заметил. Но вызов функции по-прежнему вызывает ошибку сегментации. : \ –

Смежные вопросы