在另一Cython库中使用cdef类,能否内联其cdef方法?
关于Cython跨库内联cdef类方法的问题
好问题!咱们来把这个事儿说清楚:
能不能直接跨库内联func1?
答案是要看你的编译方式和方法声明:
- 首先,Cython的
cdef方法默认是模块内部可见的。如果你的另一个库是和Cls所在模块一起编译的(比如同一项目里的多个Cython文件,最终打包成一个库),并且你把func1声明为cdef inline,那编译器(比如GCC/Clang)有很大概率会把它内联——前提是编译器能看到func1的实现代码。 - 但如果两个库是分开编译的(比如各自编译成独立的
.so/.pyd文件),那情况就不一样了:编译第二个库的时候,编译器只能看到Cls和func1的声明(通常来自.pxd文件),看不到func1的具体实现,这时候就没法做内联优化了。
替代方案:用接收Cls实例的内联函数
如果跨库内联行不通(比如分开编译的场景),你提到的“创建接收Cls指针/实例的函数”确实是更可靠的方案,具体可以这么做:
在定义
Cls的模块的.pxd文件里,导出Cls的声明和一个内联的辅助函数:# cls_module.pxd cdef class Cls: cdef inline func1(self): pass cdef inline void call_cls_func1(Cls obj): obj.func1()在另一个库的Cython代码里,你只需要导入这个
.pxd,然后直接调用call_cls_func1:# other_lib.pyx from cls_module cimport Cls, call_cls_func1 cdef void some_function(Cls my_obj): call_cls_func1(my_obj)这时候,编译器在编译
other_lib时,能看到call_cls_func1的实现(来自.pxd的内联声明),就可以把这个函数内联,进而把func1的调用也内联进去(只要func1的实现对编译器可见)。
额外提醒:纯C调用的情况
如果你的“另一库”是纯C写的,那你需要把Cls的实例转换成C能识别的结构体指针(比如Cython生成的struct __pyx_obj_xxx_Cls*,具体名字可以看编译后的C文件),然后通过C函数调用。不过这种场景下内联的可能性极低,除非你把func1的实现也暴露给C编译器(比如把代码放到头文件里)。
内容的提问来源于stack exchange,提问作者The Unfun Cat
相关产品推荐
相关产品推荐

