distutils文档
这里 指出:
针对CPython的C扩展是一个共享库(例如,在Linux上为.so文件,在Windows上为.pyd文件),它导出了一个初始化函数。
因此,关于普通共享库唯一的区别似乎在于初始化函数(除了一个合理的文件命名约定,我认为你没有任何问题)。现在,如果您查看
distutils.command.build_ext
,则会发现它定义了一个
get_export_symbols()
方法,其中:
返回共享扩展必须导出的符号列表。 这要么使用“ext.export_symbols”,要么(如果未提供)使用“PyInit_”+ module_name。 仅在Windows上相关,因为.pyd文件(DLL)必须导出模块“PyInit_”函数。
因此,对于普通的共享库,除了Windows之外,应该可以直接使用。但是解决Windows问题也很容易。
get_export_symbols()
的返回值将传递给
distutils.ccompiler.CCompiler.link()
,其文档声明:
'export_symbols'是共享库将导出的符号列表。(这似乎仅适用于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})