3

我有一个ESB。任何序列化消息都传输其自己的完全限定名称(即命名空间 + 类名)。对于每条消息,我都有一个具体的类型,它封装了要执行的特定逻辑。
每次我收到一条消息,我首先需要反序列化它,这样我才能执行它的操作——再一次,取决于它的具体类型——。

我需要一种在编译时或应用程序初始化期间注册每个类的方法。
使用 .net,我将使用反射来扫描程序集并在初始化期间发现消息类型,但是您将如何在 C++ 中做到这一点?

4

3 回答 3

3

C++ 没有反射能力。我想您可以尝试扫描目标文件等,但是没有可靠的方法可以做到这一点(AFAIK);编译器可能会完全消除或破坏某些东西。

本质上,对于序列化,您必须(半)手动进行注册。但是您可能对有助于处理琐事的序列化库感兴趣,例如Boost Serialization

于 2011-04-26T11:55:24.983 回答
1

由于在 C++ 中没有反射,我建议使用外部脚本来扫描所有相关类的源代码(如果您使用空的虚拟#defines 在源代码中注释它们,这很容易)并让它生成注册代码.

于 2011-04-26T12:02:02.033 回答
1

我个人使用手动注册的道路。如果您忘记注册......那么测试无论如何都不起作用。

你只需要使用工厂,并实现一些标签调度。例如:

typedef void (*ActOnMessageType)(Message const&);

typedef std::map<std::string, ActOnMessageType> MessageDispatcherType;

static MessageDispatcherType& GetDispatcher() {
  static MessageDispatcherType D; return D;
}

static bool RegisterMessageHandler(std::string name, ActOnMessageType func) {
  return GetDispatcher().insert(std::make_pair(name, func)).second;
}

然后你只需准备你的功能:

void ActOnFoo(Message const& m);
void ActOnBar(Message const& m);

并注册它们:

bool const gRegisteredFoo = RegisterMessageHandler("Foo", ActOnFoo);
bool const gRegisteredBar = RegsiterMessageHandler("Bar", ActOnBar);

注意:我有效地使用了一个延迟初始化的 Singleton,以允许解耦。也就是说,注册是在库加载期间完成的,因此每个Register...调用都放在定义函数的文件中。与全局变量的一个区别是,一旦初始化结束,这里的调度映射实际上是恒定的。

于 2011-04-26T12:25:37.593 回答