工厂类注册问题
工厂类一般使用模板或宏的方式,如下列代码申明:
class ExpressionFactoryRegisterer
{
public:
ExpressionFactoryRegisterer(const std::string &name, const ExpressionFactoryPtr &factory)
{
GetExpressionTable()->RegisterExpressionFactory(name, factory);
}
};
代码注册如下:
REGISTER_EXPRESSION_FACTORY("log", std::make_shared<UnaryMathExpressionFactory<Func__log>>());
这样注册之后,一个简单的"反射"机制建立起来。但一般情况下,为了避免多重定义,会降代码注册的部分写到 .cc
文件中,但静态编译的时候, .cc
生成的 .o
文件,会通过 ar
工具打包成 .a
文件,此时 .a
文件直接去链接,静态区过程会滞后,导致 RegisterExpressionFactory
动作变成运行态执行。当程序真正执行时,初始化从静态区获取不到注册的类,导致空结果或指针。
正确的方式有2种:
-
动态编译:通过
-shared
生成so
文件,然后链接; -
.o
直接链接:将生成的.o
文件直接链接,或通过ar
工具解压.a
文件,然后再链接.o
文件;