yaml-cpp在linux下的安装
下载yaml-cpp的最新版本, 目前的最新版本是yaml-cpp-0.5.1
较为通用的版本为0.3.0,使用的是old API,0.5.1使用的是new API,新老API差别很大,在参看使用wiki时,要看清楚,以免出现误用,耽误时间
yaml-cpp需要CMake提供跨平台编译,因此如果没有安装CMake,需要首先安装CMake
wget http://www.cmake.org/files/v2.8/cmake-2.8.4.tar.gz
tar zxvf cmake-2.8.4.tar.gz
./configure
make
sudo make install安装yaml-cpp
tar zxvf yaml-cpp-0.5.1.tar.gz
mkdir build
cd build
#yaml-cpp默认编译产生的是静态库,使用-DBUILD_SHARED_LIBS=ON来产生动态库
cmake -DBUILD_SHARED_LIBS=ON ..
make
sudo make install
#使库生效
sudo ldconfigcmake -DBUILD_SHARED_LIBS=ON ..运行效果
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Boost version: 1.33.1
-- Found the following Boost libraries:
-- Performing Test FLAG_WEXTRA
-- Performing Test FLAG_WEXTRA - Success
-- Configuring done
-- Generating done
-- Build files have been written to: XXX/yaml-cpp-0.5.1/buildmake运行效果
Scanning dependencies of target yaml-cpp
[ 2%] Building CXX object CMakeFiles/yaml-cpp.dir/src/node_data.cpp.o
[ 5%] Building CXX object CMakeFiles/yaml-cpp.dir/src/emitterstate.cpp.o
[ 7%] Building CXX object CMakeFiles/yaml-cpp.dir/src/scanscalar.cpp.o
[ 10%] Building CXX object CMakeFiles/yaml-cpp.dir/src/scantag.cpp.o
[ 12%] Building CXX object CMakeFiles/yaml-cpp.dir/src/parser.cpp.o
[ 15%] Building CXX object CMakeFiles/yaml-cpp.dir/src/emitter.cpp.o
.....
.....
[ 97%] Built target read
Scanning dependencies of target sandbox
[100%] Building CXX object util/CMakeFiles/sandbox.dir/sandbox.cpp.o
Linking CXX executable sandbox
[100%] Built target sandboxmake之后会看到生成的libyaml-cpp.so.0.5.1
程序中使用
由于安装的是0.5.1版本,使用的是new API,用法参照Tutorial
monster.yaml
- name: Ogre
position: [0, 5, 0]
powers:
- name: Club
damage: 10
- name: Fist
damage: 8
- name: Dragon
position: [1, 0, 10]
powers:
- name: Fire Breath
damage: 25
- name: Claws
damage: 15
- name: Wizard
position: [5, -3, 0]
powers:
- name: Acid Rain
damage: 50
- name: Staff
damage: 3自己写的小demo,test_new_api.cpp
1 #include "yaml-cpp/yaml.h"
2 #include <iostream>
3 #include <fstream>
4 #include <string>
5 #include <vector>
6
7 // our data types
8 struct Vec3 {
9 float x, y, z;
10 };
11
12 struct Power {
13 std::string name;
14 int damage;
15 };
16
17 struct Monster {
18 std::string name;
19 Vec3 position;
20 std::vector <Power> powers;
21 };
22
23 namespace YAML {
24 template<>
25 struct convert<Vec3> {
26 static Node encode(const Vec3& rhs) {
27 Node node;
28 node.push_back(rhs.x);
29 node.push_back(rhs.y);
30 node.push_back(rhs.z);
31 return node;
32 }
33
34 static bool decode(const Node& node, Vec3& rhs) {
35 if(!node.IsSequence() || node.size() != 3)
36 return false;
37
38 rhs.x = node[0].as<double>();
39 rhs.y = node[1].as<double>();
40 rhs.z = node[2].as<double>();
41 return true;
42 }
43 };
44
45 template<>
46 struct convert<Power> {
47 static Node encode (const Power& rhs) {
48 Node node;
49 node["name"] = rhs.name;
50 node["damage"] = rhs.damage;
51 return node;
52 }
53
54 static bool decode(const Node& node, Power& rhs) {
55 rhs.name = node["name"].as<std::string>();
56 rhs.damage = node["damage"].as<int>();
57 return true;
58 }
59 };
60
61 template<>
62 struct convert<Monster> {
63 static Node encode (const Monster& rhs){
64 Node node;
65 node["name"] = rhs.name;
66 node["position"] = rhs.position;
67 for(unsigned i = 0; i < rhs.powers.size(); i++) {
68 Node power_node;
69 power_node["name"] = rhs.powers[i].name;
70 power_node["damage"] = rhs.powers[i].damage;
71 node["powers"].push_back(power_node);
72 }
73 return node;
74 }
75
76 static bool decode(const Node& node, Monster& rhs) {
77 rhs.name = node["name"].as<std::string>();
78 rhs.position = node["position"].as<Vec3>();
79 const YAML::Node& powers = node["powers"];
80 for(unsigned i=0;i<powers.size();i++) {
81 Power power;
82 power = powers[i].as<Power>();
83 rhs.powers.push_back(power);
84 }
85 return true;
86 }
87 };
88 }
89
90 int main() //测试程序
91 {
92 YAML::Node config = YAML::LoadFile("monsters.yaml");
93
94 //添加新数据
95 Monster mon;
96 mon.name = "new_monster";
97 mon.position.x = 1;
98 mon.position.y = 2;
99 mon.position.z = 3;
100 Power power1;
101 power1.name = "power1";
102 power1.damage = 4;
103 Power power2;
104 power2.name = "power2";
105 power2.damage = 5;
106 mon.powers.push_back(power1);
107 mon.powers.push_back(power2);
108 config.push_back(mon);
109
110 //读取数据
111 std::vector<Monster> monsters;
112 for(unsigned i=0;i<config.size();i++) {
113 Monster monster;
114 monster = config[i].as<Monster>();
115 monsters.push_back(monster);
116 std::cout << monster.name << "\n";
117 std::cout << monster.position.x << " " << monster.position.y << " " << monster.position.z << "\n";
118 for(unsigned j = 0; j < monster.powers.size(); j++){
119 std::cout << monster.powers[j].name << " " << monster.powers[j].damage << "\n";
120 }
121 std::cout << "------------------------" << "\n";
122 }
123 return 0;
124 }编译
sudo g++ -o test_new_api -lyaml-cpp test_new_api.cpp运行
./test_new_api.cpp结果
Ogre
0 5 0
Club 10
Fist 8
------------------------
Dragon
1 0 10
Fire Breath 25
Claws 15
------------------------
Wizard
5 -3 0
Acid Rain 50
Staff 3
------------------------
new_monster
1 2 3
power1 4
power2 5
------------------------