gpt4 book ai didi

python - 使用 distutils 构建 ctypes -"based"C 库

转载 作者:IT老高 更新时间:2023-10-28 20:35:16 25 4
gpt4 key购买 nike

关注 this recommendation ,我编写了一个原生 C 扩展库来通过 ctypes 优化 Python 模块的一部分。我选择了 ctypes 而不是编写 CPython-native 库,因为它更快更容易(只有几个函数,里面有所有紧密的循环)。

我现在遇到了一个障碍。如果我希望使用 distutils 轻松安装我的工作,使用 python setup.py install ,然后 distutils 需要能够构建我的共享库并安装它(大概是 /usr/lib/<em>myproject</em> )。但是,这不是 Python 扩展模块,据我所知,distutils 无法做到这一点。

我找到了一些其他有此问题的人的引用资料:

我知道我可以做一些原生的事情,而不是使用 distutils 作为共享库,或者确实使用我的发行版的打包系统。我担心这会限制可用性,因为不是每个人都能轻松安装它。

所以我的问题是:使用 distutils 分发共享库的当前最佳方式是什么,它将被 ctypes 使用,但其他方式是 OS-native 而不是 Python 扩展模块?

如果您可以扩展它并证明为什么这是最好的方法,请随意回答上面链接的黑客之一。如果没有更好的办法,至少所有信息都在一个地方。

最佳答案

distutils 文档 here声明:

A C extension for CPython is a shared library (e.g. a .so file on Linux, .pyd on Windows), which exports an initialization function.

因此,关于普通共享库的唯一区别似乎是初始化函数(除了合理的文件命名约定,我认为您没有任何问题)。现在,如果您查看 distutils.command.build_ext,您会看到它定义了一个 get_export_symbols() 方法:

Return the list of symbols that a shared extension has to export. This either uses 'ext.export_symbols' or, if it's not provided, "PyInit_" + module_name. Only relevant on Windows, where the .pyd file (DLL) must export the module "PyInit_" function.

因此,将它用于普通共享库应该是开箱即用的,除了在 window 。但也很容易解决这个问题。 get_export_symbols() 的返回值被传递给 distutils.ccompiler.CCompiler.link(),文档说明:

'export_symbols' is a list of symbols that the shared library will export. (This appears to be relevant only on Windows.)

因此,不将初始化函数添加到导出符号就可以了。为此,您只需简单地覆盖 build_ext.get_export_symbols()

此外,您可能希望简化模块名称。下面是一个完整的 build_ext 子类示例,它可以构建 ctypes 模块以及扩展模块:

from distutils.core import setup, Extension
from distutils.command.build_ext import build_ext


class build_ext(build_ext):

def build_extension(self, ext):
self._ctypes = isinstance(ext, CTypes)
return super().build_extension(ext)

def get_export_symbols(self, ext):
if self._ctypes:
return ext.export_symbols
return super().get_export_symbols(ext)

def get_ext_filename(self, ext_name):
if self._ctypes:
return ext_name + '.so'
return super().get_ext_filename(ext_name)


class CTypes(Extension): pass


setup(name='testct', version='1.0',
ext_modules=[CTypes('ct', sources=['testct/ct.c']),
Extension('ext', sources=['testct/ext.c'])],
cmdclass={'build_ext': build_ext})

关于python - 使用 distutils 构建 ctypes -"based"C 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4529555/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com