解读NodeHandle源码(二)ros start()函数

开始简单的几行如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
boost::mutex::scoped_lock lock(g_start_mutex);
if (g_started) //如果节点已经运行,返回
{
return;
}

g_shutdown_requested = false;
g_shutting_down = false;
g_started = true;
g_ok = true;

bool enable_debug = false;
std::string enable_debug_env;
// 获得环境变量,是否DEBUG
if ( get_environment_variable(enable_debug_env,"ROSCPP_ENABLE_DEBUG") )
{
try
{
enable_debug = boost::lexical_cast<bool>(enable_debug_env.c_str());
}
catch (boost::bad_lexical_cast&)
{
}
}

下面是重要的一句:XMLRPCManager::instance()->bind("shutdown", shutdownCallback);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool XMLRPCManager::bind(const std::string& function_name, const XMLRPCFunc& cb)
{
boost::mutex::scoped_lock lock(functions_mutex_);
if (functions_.find(function_name) != functions_.end())
{
return false;
}

FunctionInfo info;
info.name = function_name;
info.function = cb;
info.wrapper.reset(new XMLRPCCallWrapper(function_name, cb, &server_));
functions_[function_name] = info;

return true;
}

几个变量的定义:

1
2
3
4
5
6
7
8
9
10
typedef boost::shared_ptr<XMLRPCCallWrapper> XMLRPCCallWrapperPtr;
struct FunctionInfo
{
std::string name;
XMLRPCFunc function;
XMLRPCCallWrapperPtr wrapper;
};
typedef std::map<std::string, FunctionInfo> M_StringToFuncInfo;
boost::mutex functions_mutex_;
M_StringToFuncInfo functions_;

关键的XMLRPCCallWrapper其实是XML-RPC服务端的子类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class XMLRPCCallWrapper : public XmlRpcServerMethod
{
public:
XMLRPCCallWrapper(const std::string& function_name, const XMLRPCFunc& cb, XmlRpcServer *s)
: XmlRpcServerMethod(function_name, s)
, name_(function_name)
, func_(cb)
{ }

void execute(XmlRpcValue &params, XmlRpcValue &result)
{
func_(params, result);
}

private:
std::string name_;
XMLRPCFunc func_;
};