关于静态编译(二)

静态编译有其优势,但有些情况下,静态编译反而会造成一些不便。

工厂类注册问题

工厂类一般使用模板或宏的方式,如下列代码申明:

class ExpressionFactoryRegisterer
{
public:
   ExpressionFactoryRegisterer(const std::string &name, const ExpressionFactoryPtr &factory)
  {
       GetExpressionTable()->RegisterExpressionFactory(name, factory);
  }
};

#define REGISTER_EXPRESSION_CONCAT_IMPL(a, b) a##b
#define REGISTER_EXPRESSION_CONCAT(a, b) REGISTER_EXPRESSION_CONCAT_IMPL(a, b)

#define REGISTER_EXPRESSION_FACTORY(name, factory)                                                       \
   namespace                                                                                           \
   {                                                                                                   \
   BS_NAMESPACE(expression)::ExpressionFactoryRegisterer                                               \
   REGISTER_EXPRESSION_CONCAT(r, __COUNTER__)(name, factory);                                           \
   }

#define REGISTER_EXPRESSION_TYPE(name, type)                                                             \
   namespace                                                                                           \
   {                                                                                                   \
   BS_NAMESPACE(expression)::ExpressionFactoryRegisterer REGISTER_EXPRESSION_CONCAT(r, __COUNTER__)(   \
           name, std::make_shared<BS_NAMESPACE(expression)::TypedExpressionFactory<type>>());           \
   }

代码注册如下:

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 文件;

这样程序会再链接的时候,将注册内容真正的放入静态区,程序启动时,直接加载到对应变量中,就不会为空啦。

Monthly Archives

Pages

Powered by Movable Type 7.9.4

About this Entry

This page contains a single entry by Cnangel published on March 7, 2023 4:43 PM.

关于静态编译(一) was the previous entry in this blog.

关于RHEL升级安装的一些问题 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.