C++ Yaml文件解析安裝及使用 yaml-cpp

安裝 yaml-cpp

克隆官方庫

git clone https://github.com/jbeder/yaml-cpp.git

編譯 yaml-cpp

cd yaml-cpp # 進入克隆的文件夾
mkdir build
cd build
cmake ..
make
make install

沒出現報錯的話就完成了編譯

示例代碼

robot.cpp

#include "yaml-cpp/yaml.h" //安裝yaml-cpp參考google code 主頁
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

// our data types //這個例子好像是取自開源遊戲引擎ogre,隨便說的
struct Vec3 { //位置座標
   float x, y, z;
};

struct Power { //招式,魔法
   std::string name; //招式名字,如 葵花寶典
   int damage; //傷害值
};

struct Monster { //怪獸
   std::string name;
   Vec3 position;
   std::vector <Power> powers;
};

// now the extraction operators for these types //重載 >> 預算符。。。。
void operator >> (const YAML::Node& node, Vec3& v) {
   node[0] >> v.x;
   node[1] >> v.y;
   node[2] >> v.z;
}

void operator >> (const YAML::Node& node, Power& power) {
   node["name"] >> power.name;
   node["damage"] >> power.damage;
}

void operator >> (const YAML::Node& node, Monster& monster) {
   node["name"] >> monster.name;
   node["position"] >> monster.position;
   const YAML::Node& powers = node["powers"];
   for(unsigned i=0;i<powers.size();i++) {
      Power power;
      powers[i] >> power;
      monster.powers.push_back(power);
   }
}

int main() //測試程序
{
   std::ifstream fin("robot.yaml"); // 讀入yaml配置文件。
   YAML::Parser parser(fin); //yaml 分析輸入的配文件。出錯拋出YAML::ParserException
   YAML::Node doc; 
   parser.GetNextDocument(doc); //doc 就是我們的yaml配置文件
   for(unsigned i=0;i<doc.size();i++) {//i的實際值是0,1,2 ;關聯yaml 中三個大的struct:ogre,dragon,wizard
      Monster monster;
      doc[i] >> monster;
      std::cout << monster.name << "\n";
   }

   return 0;
}

robot.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

編譯 robot.cpp

需要制定鏈接庫

g++ robot.cpp /usr/local/lib/libyaml-cpp.a

如果找不到的話可以使用 find 命令查找相關文件

find / -name yaml-cpp.a

如果不這樣可能會報錯:

/tmp/ccYcxLtu.o: In function `main':
robot.cpp:(.text+0x24b): undefined reference to `YAML::Parser::Parser(std::istream&)'
robot.cpp:(.text+0x25a): undefined reference to `YAML::Node::Node()'
robot.cpp:(.text+0x273): undefined reference to `YAML::Parser::GetNextDocument(YAML::Node&)'
robot.cpp:(.text+0x30f): undefined reference to `YAML::Node::size() const'
robot.cpp:(.text+0x331): undefined reference to `YAML::Node::~Node()'
robot.cpp:(.text+0x340): undefined reference to `YAML::Parser::~Parser()'
robot.cpp:(.text+0x388): undefined reference to `YAML::Node::~Node()'
robot.cpp:(.text+0x39c): undefined reference to `YAML::Parser::~Parser()'
/tmp/ccYcxLtu.o: In function `YAML::Node const* YAML::Node::FindValueForKey<std::string>(std::string const&) const':

就是一堆找不到庫文件

運行結果

Ogre
Dragon
Wizard

難點分析與總結

總結一下知識忙點和誤區

什麼是 .a 與 .so 文件

靜態鏈接庫(.a) 與動態鏈接庫(.so)

在這裏插入圖片描述

  • 庫有兩種,一種是 靜態鏈接庫,一種是 動態鏈接庫,不管是哪一種庫,要使用它們,都要在程序中包含相應的 include 頭文件

靜態鏈接庫

  • 靜態鏈接庫 即在鏈接階段,將源文件中用到的庫函數與彙編生成的目標文件.o合併生成可執行文件。該可執行文件可能會比較大。這種鏈接方式的好處是:方便程序移植,因爲可執行程序與庫函數再無關係,放在如何環境當中都可以執行。
    缺點是:文件太大
  • 靜態鏈接的使用, 需要找到文件的位置和庫文件名
      g++ -o test test.cpp -L./addlib -ladd
    
    -L是指定加載庫文件的路徑
    
    -l是指定加載的庫文件。
    

動態鏈接庫

在這裏插入圖片描述

在這裏插入圖片描述

g++(gcc)編譯選項

  • -shared :指定生成動態鏈接庫。
  • -static :指定生成靜態鏈接庫。
  • -fPIC :表示編譯爲位置獨立的代碼,用於編譯共享庫。目標文件需要創建成位置無關碼,念上就是在可執行程序裝載它們的時候,它們可以放在可執行程序的內存裏的任何地方。
  • -L. :表示要連接的庫所在的目錄。
  • -l:指定鏈接時需要的動態庫。編譯器查找動態連接庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.a/.so來確定庫的名稱。
  • -Wall :生成所有警告信息。
  • -ggdb :此選項將儘可能的生成gdb的可以使用的調試信息。
  • -g :編譯器在編譯的時候產生調試信息。
  • -c :只激活預處理、編譯和彙編,也就是把程序做成目標文件(.o文件)。
  • -Wl,options :把參數(options)傳遞給鏈接器ld。如果options中間有逗號,就將options分成多個選項,然後傳遞給鏈接程序。

參考文章

  1. C/C++ 靜態鏈接庫(.a) 與 動態鏈接庫(.so) http://www.cnblogs.com/52php/p/5681711.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章