我正在尝试创建一个配置类,它使用rapidxml从xml读取数据。因此,我有一个私有xml_document
,我在构造函数内解析:
class Config
{
public:
Config();
~Config();
/*returns the first found node*/
xml_node<>* findNode(const char* name);
/*get an configuration value. It's always a char*/
char* getConfigValue(const char* name);
private:
rapidxml::xml_document<>* m_doc;
};
//cpp
Config::Config()
{
m_doc = new xml_document<>();
rapidxml::file<> xmlFile("config.xml");
m_doc->parse<0>(xmlFile.data());
//LOG(getConfigValue("width")); // here it works
}
xml_node<>* Config::findNode(const char* name)
{
return m_doc->first_node()->first_node(name);
}
char* Config::getConfigValue(const char* name){
return m_doc->first_node()->first_node(name)->value();
}
在qazxsw poi里面我创建了一个配置对象并尝试调用这些方法。
wWinMain
但是,如果我将相同的行放入Config类的构造函数中,它可以正常工作。这里出了什么问题?
我不熟悉快速xml,但快速谷歌搜索告诉我:
Config* config = new Config();
LOG(config->findNode("width")->value()); // this does create violation reading
RapidXml是一种原位解析器,它可以实现非常高的解析速度。原位意味着解析器不会复制字符串。相反,它将指针放在DOM层次结构中的源文本中。
3.1源文本的生命周期
原位解析要求源文本至少与文档对象一样长。如果源文本被销毁,DOM树中节点的名称和值也将被销毁。此外,空格处理,字符实体转换和字符串零终止要求在解析期间修改源文本(但请参阅非破坏性模式)。这使得文本在RapidXml解析后无法进行进一步处理。
所以我从中得到的是你不能只拥有rapidxml :: file <> xmlFile(“config.xml”);是一个堆栈变量,因为xml_document-> parse()将创建一个直接指向xmlFile内存的树。所以xmlFile必须在内存中至少与xml_document一样长,否则你将拥有无效数据。这意味着xmlFile需要是Config类的成员。另外,我没有看到你初始化m_doc,你刚刚省略了一些代码吗?否则它应该早点抱怨而且永远不会工作。此外,您应该始终检查以确保返回指针的函数在访问之前不返回null,以避免读取违规。
所以你真正想要的是这样的:
http://rapidxml.sourceforge.net/manual.html