python - 将调用 C 函数的 Python 2.7 代码移植到 Python 3.4

标签 python c python-3.x shared-libraries ctypes

我正在尝试从 Python 3.4.so 文件调用 C 函数。我已经进行了一些必要的更改,以使 Python 2.7 代码能够与 Python 3.4 配合使用,但我仍然遇到 致命 Python 错误:段错误

代码来自这个Bitbucket hosted project 。我已经通过 pip3 安装了它(pip3 install Lemmagen),它还创建了我尝试从 Python3 使用的 .so 文件。

这里是原始的 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.x 中是默认的。我仍然 80% 确定这是一个字符编码问题。我必须使用什么编码来将字符串变量传递给函数调用 self._lib.lem_lemmatize_word(word, self._output_buffer)?这正是发生段错误的行:

致命的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)

我一直在尝试阅读我的确切问题(编码类型),但到目前为止我发现的任何内容似乎都无法解决这个问题。我希望得到一些有关这方面的深思熟虑的信息。谢谢。

感谢任何在没有任何理由或任何评论的情况下否决该问题的人。

最佳答案

您需要使用 create_string_buffer 函数创建一个 char 数组,然后再将其传递给该函数。

这样的事情应该有效:

    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()

此输出:

pim@pim-desktop:~/slovene_lemmatizer/bin$ python3 main.py [错误] 必须首先加载词形还原器的语言文件! 测试 pim@pim-desktop:~/slovene_lemmatizer/bin$

编辑:虽然我不能 100% 确定这里使用的“raw”属性是否正确,但它确实有效! Edit2:它确实可以在没有原始属性的情况下工作,更新了 awnser

关于python - 将调用 C 函数的 Python 2.7 代码移植到 Python 3.4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32988834/

相关文章:

python - 如何使用 Python 中的列表生成所有可能的排列对?

python - cPickle 数据量非常大

python - 边不显示在使用 Networkx 的图形中 - Python

c - 简单可执行文件的 slurm 示例

c - C中哈希表插入函数的问题

python - 如果条件不那么困惑

python - 在多列上并行运行回归

python - Django模型针对这种反向ForeignKey的最佳解决方案

c - 带有调试信息的二进制文件的 objdump 产生损坏的输出

python - 转换数据帧值