php的一些组件,既可以静态编译进php本身,也可以用so的方式来动态加载。静态编译的模式不说,如果是共享库so的方式,肯定是用dlopen的方式,那就需要这个so有一个方法名已知的函数暴露出来,使用dlsym来调用。仔细看扩展预先生成的源码,以hanks这个扩展为例:
#ifdef COMPILE_DL_HANKS
ZEND_GET_MODULE(hanks)
#endif
COMPILE_DL_HANKS 决定了要不要以dll(.so)的方式来编译hanks这个扩展,如果dll方式,则ZEND_GET_MODULE这个宏就会发生作用。
ZEND_GET_MODULE定义如下:
#define ZEND_GET_MODULE(name) \
BEGIN_EXTERN_C()\
ZEND_DLEXPORT zend_module_entry *get_module(void) { return &name##_module_entry; }\
END_EXTERN_C()
BEGIN_EXTERN_C 就是extern "C" {,其实这里暴露出来的就是 get_module 方法,dlsym(dl,'get_module')就会返回这个函数指针,调用后就返回 hanks_module_entry 这个zend_module_entry结构体,包含这个模块的相关信息和方法,这样php就能完全掌握这个模块,融入内部的体系中。