如何为CFFI重命名/重新声明带冗长前缀的C库函数?
优化带冗长前缀的C库CFFI绑定方案需求
我正在为某C库采用out-of-line API模式创建CFFI绑定,目标库为PQClean,但需求也适用于其他同类库,避免重复修改上游C源码的工作。
该库的每个函数都带有冗长前缀,例如GreenSpam子模块的AVX优化foo函数名为THELIBRARY_GREENSPAM_OPTIMIZED_AVX_foo(),我希望将其暴露为TheLibrary.Spam.GreenSpam.foo,同时实现导入时自动选择CPU优化方案。
目前我能在ffibuilder.compile()阶段确定每个模块的前缀,希望最大程度遵循DRY原则,但现有代码重复度极高,且难以实现运行时算法选择。我期望在ffi.compile()阶段通过类似正则替换规则(如(fr'\b{re.escape(prefix)}_(\w+)\b', r'\1'))简化这些C库函数名,生成别名,让绑定代码更简洁。
由于希望尽量贴合上游库,我不想修改C源码,正在寻求替代方案——比如在ffibuilder.set_source()阶段为冗长名称添加规范化别名(曾尝试函数引用,但该方式似乎仅支持C++)。
当前代码示例
TheLibrary/Spam/GreenSpam.py
from . import _greenspam_generic from . import _greenspam_optimized_avx # TODO __all__ = ['foo', 'oof'] def foo(bar): """GreenSpam foo""" _out = _greenspam_generic.ffi.new(f"uint8_t[{len(bar):d}]") _greenspam_generic.lib.THELIBRARY_GREENSPAM_GENERIC_foo(bar, len(bar), _out) # void function never errors return bytes(_out) def oof(baz): """GreenSpam oof""" _out = _greenspam_generic.ffi.new(f"uint8_t[{len(baz):d}]") err = _greenspam_generic.lib.THELIBRARY_GREENSPAM_GENERIC_oof(baz, len(baz), _out) if err: raise RuntimeError("oof") return bytes(_out)
TheLibrary/Spam/PurpleSpam.py
from . import _purplespam_generic from . import _purplespam_optimized_avx # TODO __all__ = ['foo', 'oof'] def foo(bar): """PurpleSpam foo""" _out = _purplespam_generic.ffi.new(f"uint8_t[{len(bar):d}]") _purplespam_generic.lib.THELIBRARY_PURPLESPAM_GENERIC_foo(bar, len(bar), _out) # void function never errors return bytes(_out) def oof(baz): """PurpleSpam oof""" _out = _purplespam_generic.ffi.new(f"uint8_t[{len(baz):d}]") err = _purplespam_generic.lib.THELIBRARY_PURPLESPAM_GENERIC_oof(baz, len(baz), _out) if err: raise RuntimeError("oof") return bytes(_out)
内容的提问来源于stack exchange,提问作者JamesTheAwesomeDude
相关产品推荐
相关产品推荐

