├── LICENSE ├── README.wiki └── libs ├── README.wiki ├── cpp.wiki └── python.wiki /LICENSE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | -------------------------------------------------------------------------------- /README.wiki: -------------------------------------------------------------------------------- 1 | = 俺收藏的开源项目 = 2 | 3 | == 开源库及示例代码 == 4 | 5 | 本目录放置:面向程序员的开源代码库清单(含示例代码)。 6 | 7 | 为了方便查找,根据“编程语言”归类。(目前先整理两个编程语言,今后有空再补充其它语言) 8 | 9 | * [/libs/cpp.wiki C/C++] 10 | * [/libs/python.wiki Python] 11 | 12 | == 开源软件 == 13 | 14 | (俺会抽空整理) 15 | -------------------------------------------------------------------------------- /libs/README.wiki: -------------------------------------------------------------------------------- 1 | = 开源库及示例代码 = 2 | 3 | 本目录放置:面向程序员的开源代码库清单(含示例代码)。 4 | 5 | 为了方便查找,根据“编程语言”归类。(目前先整理两个编程语言,今后有空再补充其它语言) 6 | 7 | * [/libs/cpp.wiki C/C++] 8 | * [/libs/python.wiki Python] 9 | -------------------------------------------------------------------------------- /libs/cpp.wiki: -------------------------------------------------------------------------------- 1 |

C/C++ 开源库及示例代码

2 | 3 | = = 4 | 5 | = 说明 = 6 | 7 | 本页面汇总俺收集的各种 C 和 C++ 的开源代码库,不定期更新。 8 | 9 | 如果你发现本页面的开源库有错漏之处,非常欢迎给俺提供反馈——有 GitHub 帐号的同学,可以[https://github.com/programthink/opensource/issues 给俺发 issue];没帐号的同学,可以去[http://program-think.blogspot.com/ 俺博客]留言。 10 | 11 | ---- 12 | 13 | = 1 综合性的库 = 14 | 15 |

Boost

16 | 17 | Home:[http://boost.org/] 18 | 19 | Links:[https://en.wikipedia.org/wiki/Boost_%28C%2B%2B_libraries%29 Wikipedia] [https://zh.wikipedia.org/wiki/Boost_C%2B%2B_Libraries 维基百科] 20 | 21 | Boost 大概是最重要的第三方 C++ 库。其作者有很多是 C++ 标准委员会的成员。Boost 的很多子库后来都成为 C++ 的标准库。 22 | 23 | 本页面的其它章节还会继续提及 Boost 在各种领域的应用。 24 | 25 |

wxWidgets

26 | 27 | Home:[https://wxwidgets.org/] 28 | 29 | Links:[https://en.wikipedia.org/wiki/WxWidgets Wikipedia] [https://zh.wikipedia.org/wiki/WxWidgets 维基百科] 30 | 31 | 这是一个非常老牌的 C++ 开源 GUI 框架,诞生于1992年。原先叫做 wxWindows,后来因为微软的法律纠纷,改为现名。 32 | 33 | 它支持的操作系统平台很多(包括嵌入式系统)。 34 | 35 | 很多开源项目用到它,比如:BitTorrent、aMule、FileZilla、Code::Blocks、Dolphin...... 36 | 37 | 虽然它以 GUI 为主,但是也提供了其它一些辅助功能(比如:进程间通讯、网络、数据库、多媒体......) 38 | 39 |

Qt

40 | 41 | Home:[http://www.qt-project.org/] 42 | 43 | Links:[https://en.wikipedia.org/wiki/Qt_(toolkit) Wikipedia] [https://zh.wikipedia.org/wiki/Qt 维基百科] 44 | 45 | 这是一个非常老牌的 C++ 开源 GUI 框架,于1995年发布 1.0 版本。原先由 Trolltech 公司维护,后来该公司被 Nokia 收购。 46 | 47 | 它支持的操作系统平台很多(包括嵌入式系统)。 48 | 49 | 虽然它以 GUI 为主,但是也提供了其它一些辅助功能(比如:网络、数据库、多媒体、3D引擎......) 50 | 51 |

APR(Apache Portable Runtime)

52 | 53 | Home:[https://apr.apache.org/] 54 | 55 | Links:[https://en.wikipedia.org/wiki/Apache_Portable_Runtime Wikipedia] [https://zh.wikipedia.org/wiki/Apache%E5%8F%AF%E7%A7%BB%E6%A4%8D%E8%BF%90%E8%A1%8C%E6%97%B6 维基百科] 56 | 57 | 这是由 Apache 社区维护的 C 开源库,主要提供操作系统相关的功能(文件系统、进程、线程、用户、IPC)。此外还提供了一些网络相关的功能。 58 | 59 | APR 原先是 Apache Web 服务器的一个组成部分,后来独立出来,成为一个单独的开源项目。 60 | 61 |

ACE(Adaptive Communication Environment)

62 | 63 | Home:[http://www.cse.wustl.edu/~schmidt/ACE.html] 64 | 65 | Links:[https://en.wikipedia.org/wiki/Adaptive_Communication_Environment Wikipedia] [https://zh.wikipedia.org/wiki/ACE%E8%87%AA%E9%80%82%E9%85%8D%E9%80%9A%E4%BF%A1%E7%8E%AF%E5%A2%83 维基百科] 66 | 67 | 这是一个跨平台的 C++ 库,提供了一套网络通讯的框架;另外还支持线程、进程和 IPC。 68 | 69 |

POCO

70 | 71 | Home:[http://pocoproject.org/] 72 | 73 | Links:[https://en.wikipedia.org/wiki/POCO_C%2B%2B_Libraries Wikipedia] 74 | 75 | 它的名称源自“POrtable COmponents”,是一个基于 C++ 的开源库。 76 | 77 | 它的功能以网络通讯为主,同时也提供一些其它功能(比如:多线程、进程间通讯、数据库、XML、JSON......) 78 | 79 |

Dlib

80 | 81 | Home:[http://dlib.net/] 82 | 83 | Links:[https://en.wikipedia.org/wiki/Dlib Wikipedia] 84 | 85 | 诞生于2002年的 C++ 开源库,提供了非常多的功能(网络、多线程、GUI、数值计算、图像处理、数据挖掘......)。 86 | 87 | 它还有一个特色是:同时提供了 Python API :) 88 | 89 |

Crypto++

90 | 91 | Home:[http://www.cryptopp.com/] 92 | 93 | Links:[https://en.wikipedia.org/wiki/Crypto%2B%2B Wikipedia] 94 | 95 | 它也叫“CryptoPP”或“libcrypto++”,是非常著名的开源加密库,诞生于1995年。基于 C++ 开发,大量用到模板语法。 96 | 97 | 虽然它以加密为主,但是也提供了其它一些辅助功能(比如:数据压缩、编码解码、计时器...) 98 | 99 | ---- 100 | 101 | = 2 数据结构 & 算法 = 102 | 103 | == 2.1 容器 == 104 | 105 | === 2.1.1 标准容器 === 106 | 107 |

std

108 | 109 | C++ 98 标准内置的 STL 提供了如下容器: 110 | 111 | * 数组:vector(动态数组)、valarray(针对数值类型特化的 vector)、bitset(储存比特的【固定】数组) 112 | 113 | * 链表:list(双向) 114 | 115 | * 队列:queue、deque(双端队列) 116 | 117 | * 栈:stack 118 | 119 | * 映射:map(键值无重复)、multimap(键值可重复) 120 | 121 | * 集合:set(元素无重复)、multiset(元素可重复) 122 | 123 | [https://en.wikipedia.org/wiki/C%2B%2B11 C++ 11 标准]新增了如下容器: 124 | 125 | * 数组:array(相比 vector,它的 size 是编译时【固定】的) 126 | 127 | * 链表:forward_list(相比 list,它是【单向】的) 128 | 129 | * 映射:unordered_map、unordered_multimap(相比 map 和 multimap,这俩采用 hash 实现) 130 | 131 | * 集合:unordered_set、unordered_multiset(相比 set 和 multiset,这俩采用 hash 实现) 132 | 133 | 下面几个容器,C++ 标准【没有】包含,但包含在某些知名的 STL 第三方库中(比如 SGI 的 STL): 134 | 135 | * 映射:hash_map、hash_multimap(与 unordered_map、unordered_multimap 相同) 136 | 137 | * 集合:hash_set、hash_multiset(与 unordered_set、unordered_multiset 相同) 138 | 139 | === 2.1.2 Lockfree 的容器 === 140 | 141 | (“lock-free”翻译成“锁无关”会引发歧义,所以俺直接用洋文) 142 | 143 |

Boost.Lockfree

144 | 145 | Docs:[http://boost.org/libs/lockfree] 146 | 147 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了三种 lock-free 的容器(queue、stack、spsc_queue)。最后这种是“环形缓冲”。 148 | 149 |

libcds(Concurrent Data Structures)

150 | 151 | Home:[http://libcds.sourceforge.net/] 152 | 153 | 这是一个跨平台的 C++ 开源库,提供了若干 lock-free 的容器。它的 2.0.0 版本,代码重写以支持 C++ 11 标准。 154 | 155 | === 2.1.3 环形缓冲 === 156 | 157 |

Boost.CircularBuffer

158 | 159 | Docs:[http://boost.org/libs/circular_buffer] 160 | 161 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“环形缓冲区”的模板。 162 | 163 | “环形缓冲区”可以降低内存分配的开销。俺曾经写过一篇博文推荐环形缓冲区(在“[http://program-think.blogspot.com/2009/04/producer-consumer-pattern-3-circle.html 这里]”)。 164 | 165 | 代码示例 166 | 167 | #include 168 | 169 | boost::circular_buffer cb(3); // Create with capacity for 3 integers 170 | cb.push_back(1); 171 | cb.push_back(2); 172 | cb.push_back(3); 173 | 174 | // The buffer is full now 175 | // pushing subsequent elements will overwrite front-most elements. 176 | 177 | cb.push_back(4); // Overwrite 1 with 4. 178 | cb.push_back(5); // Overwrite 2 with 5. 179 | // The buffer now contains 3, 4 and 5. 180 | 181 | // Elements can be popped from either the front or the back. 182 | cb.pop_back(); // 5 is removed. 183 | cb.pop_front(); // 3 is removed. 184 | 185 | // Leaving only one element with value = 4. 186 | assert(cb[0] == 4); 187 | 188 | 189 | === 2.1.4 多维数组 === 190 | 191 |

Boost.MultiArray

192 | 193 | Docs:[http://boost.org/libs/multi_array] 194 | 195 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了任意维的数组。 196 | 197 | 代码示例——3维数组 198 | 199 | #include 200 | 201 | typedef boost::multi_array array_type; 202 | typedef array_type::index index; 203 | array_type A(boost::extents[3][4][2]); 204 | 205 | int values = 0; 206 | for(index i=0; i!=3; ++i) 207 | for(index j=0; j!=4; ++j) 208 | for(index k=0; k!=2; ++k) 209 | A[i][j][k] = values++; 210 | 211 | 212 | === 2.1.5 图 === 213 | 214 |

Boost.Graph

215 | 216 | Docs:[http://boost.org/libs/graph] 217 | 218 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,简称 BGL(Boost Graph Library),封装了“图”这种数据结构。 219 | 220 | 它提供了与 STL 类似的泛型编程风格。 221 | 222 |

Dlib

223 | 224 | Docs:[http://dlib.net/graph_tools.html] 225 | 226 | Dlib 前面已经介绍过。它提供了2个类(graph & directed_graph)封装“图”。 227 | 228 | == 2.2 对容器的操作 == 229 | 230 | (STL 标准库里面已经实现了很多算法用来操作容器,考虑到本页面已经很长,这里只列举第三方库实现的算法) 231 |

Boost.Foreach

232 | 233 | Docs:[http://boost.org/libs/foreach] 234 | 235 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了通用的遍历,其效果类似于 Python 的 for 循环语法。 236 | 237 | 有了它,你在遍历时无需声明迭代器变量,也无需关心遍历的容器是何种类型。 238 | 239 | 代码示例——遍历字符串 240 | 241 | #include 242 | #include 243 | #include 244 | 245 | std::string test("Hello, world!"); // string 可以视为 char 的容器 246 | BOOST_FOREACH(char ch, test) 247 | { 248 | std::cout << ch; 249 | } 250 | 251 | 252 | == 2.3 字符串处理 == 253 | 254 | === 2.3.1 字符集 === 255 | 256 |

Boost.Locale

257 | 258 | Docs:[http://boost.org/libs/locale] 259 | 260 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了各种“本地化”的功能。其中就包括字符集编码转换。 261 | 262 | 代码示例 263 | 264 | #include 265 | #include 266 | 267 | using namespace boost::locale; 268 | std::locale loc = generator().generate("he_IL.UTF-8"); 269 | std::wofstream file. 270 | file.imbue(loc); 271 | file.open("hello.txt"); 272 | file << L"שלום!"; 273 | 274 | 275 |

POCO.Text

276 | 277 | Docs:[http://pocoproject.org/docs/package-Foundation.Text.html] 278 | 279 | POCO 前面已经介绍过。它提供了 UTF8/UTF16/UTF32 的转换。 280 | 281 | === 2.3.2 字符串格式化 === 282 | 283 |

Boost.Format

284 | 285 | Docs:[http://boost.org/libs/format] 286 | 287 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“格式化字符串”的功能。相比 ANSI C 的 sprintf() 和 snprintf(),它的格式化功能更强并且更安全。 288 | 289 | 代码示例 290 | 291 | #include 292 | #include 293 | 294 | using std::cout; 295 | using boost::format; 296 | 297 | // 基于“位置指示符”的格式串语法 298 | cout << format("%1% %2% %3% %2% %1%") % "11" % "22" % "333"; 299 | // 输出如下: 300 | // 11 22 333 22 11 301 | 302 | // 兼容 printf() 的格式串语法 303 | cout << format("%s %d") % "price" % 1234; 304 | // 输出如下: 305 | // price 1234 306 | 307 | 308 |

fmt

309 | 310 | Home:[https://github.com/fmtlib/fmt] 311 | 312 | 这是一个轻量级、类型安全、高性能的字符串格式化库。它也可以用来替代 C++ 标准库中的 IOStreams。 313 | 314 | 代码示例 315 | 316 | #include 317 | #include 318 | 319 | // 使用 Python 的格式化语法 320 | fmt::print("Hello, {}!", "world"); 321 | // 使用 printf 的格式化语法 322 | fmt::printf("Hello, %s!", "world"); 323 | // 使用序号参数, 324 | std::string s = fmt::format("{0} {1} {0}", "Hello", "world"); 325 | // 使用命名参数 326 | fmt::print("Hello, {name}! The answer is {number}. Goodbye, {name}.", 327 | fmt::arg("name", "World"), fmt::arg("number", 42)); 328 | 329 | 330 | === 2.3.3 正则表达式 === 331 | 332 |

PCRE(Perl Compatible Regular Expressions)

333 | 334 | Home:[http://www.pcre.org/] 335 | 336 | Links:[https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions Wikipedia] 337 | 338 | 这是一个很老牌的正则表达式的库,诞生于1997年。很多知名的开源项目(Apache、PHP、KDE)用到了它。 339 | 340 |

Boost.Regex

341 | 342 | Docs:[http://boost.org/libs/regex] 343 | 344 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“正则式”的功能。 345 | 346 | 注:Boost 的这个子库已经进入 C++ 11 标准。 347 | 348 | 代码示例——基于正则式进行匹配和替换 349 | 350 | #include 351 | 352 | using std::string; 353 | using namespace boost; 354 | 355 | // 正则式匹配的例子 356 | bool validate_card_format(const string& s) 357 | { 358 | const regex e("(\\d{4}[- ]){3}\\d{4}"); 359 | return regex_match(s, e); 360 | } 361 | 362 | // 正则式替换的例子 363 | const regex e("\\A(\\d{3,4})[- ]?(\\d{4})[- ]?(\\d{4})[- ]?(\\d{4})\\z"); 364 | const string machine_format("\\1\\2\\3\\4"); 365 | const string human_format("\\1-\\2-\\3-\\4"); 366 | 367 | string machine_readable_card_number(const string& s) 368 | { 369 | return regex_replace(s, e, machine_format, match_default|format_sed); 370 | } 371 | 372 | string human_readable_card_number(const string& s) 373 | { 374 | return regex_replace(s, e, human_format, match_default|format_sed); 375 | } 376 | 377 | 378 |

re2

379 | 380 | Home:[https://github.com/google/re2] 381 | 382 | 这是 Google 提供的正则式库,基于 C++。其 API 使用起来很简洁。 383 | 384 | 有多种脚本语言(Python、Ruby、Perl、Node.js、Erlang、OCaml)提供了对它的封装。 385 | 386 | 代码示例——基于正则式进行匹配 387 | 388 | #include 389 | 390 | int i; 391 | string s; 392 | assert(RE2::FullMatch("test:1234", "(\\w+):(\\d+)", &s, &i)); 393 | assert(s == "test"); 394 | assert(i == 1234); 395 | 396 | 397 |

Oniguruma(鬼车)

398 | 399 | Home:[http://www.geocities.jp/kosako3/oniguruma/] 400 | 401 | Links:[https://en.wikipedia.org/wiki/Oniguruma Wikipedia] 402 | 403 | 来自日本的正则式库,基于 C 语言。据说性能很高。 404 | 405 | 它被用在 Ruby、TextMate、Sublime Text、SubEthaEdit 等软件上。 406 | 407 |

POCO.RegExp

408 | 409 | Docs:[http://pocoproject.org/docs/package-Foundation.RegExp.html] 410 | 411 | POCO 前面已经介绍过。它提供了正则表达式的封装类。 412 | 413 |

Qt.QRegExp

414 | 415 | Docs:[http://doc.qt.io/qt-4.8/qregexp.html] 416 | 417 | Qt 前面已经介绍过。这是 Qt 中的一个类,提供了“正则式”的功能。 418 | 419 | === 2.3.4 (其它) === 420 | 421 |

Boost.StringAlgorithms

422 | 423 | Docs:[http://boost.org/libs/algorithm/string] 424 | 425 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了各种字符串的算法(替换、合并、拆分、大小写转换、trim......)。 426 | 427 | 代码示例——字符串合并 428 | 429 | #include 430 | #include 431 | #include 432 | #include 433 | 434 | std::vector v; 435 | // 此处填充 v 436 | std::cout << boost::algorithm::join(v, " ") << '\n'; 437 | 438 | 439 |

Boost.Lexical_Cast

440 | 441 | Docs:[http://boost.org/libs/lexical_cast] 442 | 443 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了各种字符串与其它类型的转换。 444 | 445 | 注:Boost 的这个子库已经进入 C++ 11 标准。 446 | 447 | 代码示例 448 | 449 | #include 450 | #include 451 | #include 452 | 453 | std::string s = boost::lexical_cast(123); 454 | std::cout << s << '\n'; 455 | 456 | double d = boost::lexical_cast(s); 457 | std::cout << d << '\n'; 458 | 459 | 460 | == 2.4 内存相关 == 461 | 462 | === 2.4.1 智能指针 === 463 | 464 |

Boost.SmartPointers

465 | 466 | Docs:[http://boost.org/libs/smart_ptr] 467 | 468 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了几种智能指针。最常用的是“shared_ptr”。 469 | 470 | 有了智能指针,你就无需操心 new 之后的 delete 了。 471 | 472 | 注:Boost 的这个子库已经进入 C++ 11 标准。 473 | 474 | === 2.4.2 内存池 === 475 | 476 |

Boost.Pool

477 | 478 | Docs:[http://boost.org/libs/pool] 479 | 480 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“内存池”的功能。 481 | 482 |

Dlib

483 | 484 | Docs:[http://dlib.net/other.html] 485 | 486 | Dlib 前面已经介绍过。它提供了内存池(参见文档中以“memory_manager”开头的类)。 487 | 488 |

APR

489 | 490 | Docs:[https://apr.apache.org/docs/apr/trunk/modules.html] 491 | 492 | APR 前面已经介绍过。它提供了内存池的功能。 493 | 494 | == 2.5 时间 & 日期 == 495 | 496 |

Boost.Date_Time

497 | 498 | Docs:[http://boost.org/libs/date_time] 499 | 500 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了针对“日期 和 时间”的各种处理。 501 | 502 |

POCO.DateTime

503 | 504 | Docs:[http://pocoproject.org/docs/package-Foundation.DateTime.html] 505 | 506 | POCO 前面已经介绍过。它提供了若干个日期和时间的封装类(时区转换、格式化字符串、解析时间字符串)。 507 | 508 | == 2.6 编码 & 解码 == 509 | 510 | === 2.6.1 序列化 === 511 | 512 |

Boost.Serialization

513 | 514 | Docs:[http://boost.org/libs/serialization] 515 | 516 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了【可定制的】“序列化”功能。 517 | 518 | === 2.6.2 Base64 === 519 | 520 | [https://en.wikipedia.org/wiki/Base64 Base64] 是一组编码算法的总称。用于把二进制数据编码为文本。 521 | 522 |

Boost.Serialization

523 | 524 | Docs:[http://boost.org/libs/serialization] 525 | 526 | Boost 前面已经介绍过。使用前面提到的“Boost.Serialization”,你可以定制采用 Base64 方式进行编码和解码。 527 | 528 |

Crypto++

529 | 530 | Docs:[http://www.cryptopp.com/docs/ref/annotated.html] 531 | 532 | Crypto++ 前面已经介绍过。它提供了6个类,分别用于 Base64、Base32、Base16 的编码/解码。 533 | 534 |

POCO.Streams

535 | 536 | Docs:[http://pocoproject.org/docs/package-Foundation.Streams.html] 537 | 538 | POCO 前面已经介绍过。它提供了 Base64 和 Base32 的编码/解码。 539 | 540 | == 2.7 (其它) == 541 | 542 | === 2.7.1 随机数 === 543 | 544 |

std

545 | 546 | ANSI C 在 stdlib.h 中提供了随机数生成函数 rand()。使用前记得先用 srand() 函数播种,否则就傻了。 547 | 548 |

Boost.Random

549 | 550 | Docs:[http://boost.org/libs/random] 551 | 552 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“随机数生成”的功能。 553 | 554 | 相比 ANSI C 的随机数函数,它提供的功能更丰富。 555 | 556 | 代码示例 557 | 558 | #include 559 | #include 560 | 561 | double SampleNormal(double mean, double sigma) 562 | { 563 | using namespace boost; 564 | 565 | // 建立一个 Mersenne twister 随机数产生器,使用当前时间播种 566 | static mt19937 rng(static_cast(std::time(NULL))); 567 | 568 | // 选择高斯机率分布 569 | normal_distribution norm_dist(mean, sigma); 570 | 571 | // 使用 function 的形式,生成随机数据产生器 572 | variate_generator > normal_sampler(rng, norm_dist); 573 | 574 | // 传回样本分布结果 575 | return normal_sampler(); 576 | } 577 | 578 | 579 |

Crypto++

580 | 581 | Docs:[http://www.cryptopp.com/docs/ref/class_random_number_generator.html] 582 | 583 | Crypto++ 前面已经介绍过。它提供了好几个类,用于随机数生成。 584 | 585 | === 2.7.2 UUID === 586 | 587 |

Boost.UUID

588 | 589 | Docs:[http://boost.org/libs/uuid] 590 | 591 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了 UUID 的生成。 592 | 593 | 代码示例——生成 UUID 594 | 595 | #include 596 | #include 597 | 598 | // uuid 类以 POD 方式实现,可以直接用在 memcpy() 599 | unsigned char uuid_data[16]; 600 | boost::uuids::uuid u; 601 | memcpy(&u, uuid_data, 16); 602 | 603 | 604 |

APR

605 | 606 | Docs:[https://apr.apache.org/docs/apr/trunk/modules.html] 607 | 608 | APR 前面已经介绍过。它提供了 UUID 的生成、格式化成字符串、解析 UUID 字符串。 609 | 610 |

POCO.UUID

611 | 612 | Docs:[http://pocoproject.org/docs/package-Foundation.UUID.html] 613 | 614 | POCO 前面已经介绍过。它提供了 UUID 的生成、格式转换。 615 | 616 | ---- 617 | 618 | = 3 编程范式 = 619 | 620 | (这一章节主要针对 C++——“支持多范式”是 C++ 的一大特色) 621 | 622 | == 3.1 面向对象编程(OOP) == 623 | 624 |

fruit

625 | 626 | Home:[https://github.com/google/fruit] 627 | 628 | 它是 Google 开发的 C++ 库,提供了“依赖注入”([https://en.wikipedia.org/wiki/Dependency_injection dependency injection])的框架。 629 | 630 | 代码示例——一个简单的例子 631 | 632 | #include 633 | #include 634 | 635 | using fruit::Component; 636 | using fruit::Injector; 637 | 638 | class Writer 639 | { 640 | public: 641 | virtual void write(std::string str) = 0; 642 | }; 643 | 644 | class StdoutWriter : public Writer 645 | { 646 | public: 647 | // Like "StdoutWriter() = default;" but also marks this constructor as the 648 | // one to use for injection. 649 | INJECT(StdoutWriter()) = default; 650 | 651 | virtual void write(std::string str) override 652 | { 653 | std::cout << str; 654 | } 655 | }; 656 | 657 | class Greeter 658 | { 659 | public: 660 | virtual void greet() = 0; 661 | }; 662 | 663 | class GreeterImpl : public Greeter 664 | { 665 | private: 666 | Writer* writer; 667 | 668 | public: 669 | // Like "GreeterImpl(Writer* writer) {...}" 670 | // but also marks this constructor as the one to use for injection. 671 | INJECT(GreeterImpl(Writer* writer)) 672 | : writer(writer) 673 | { 674 | } 675 | 676 | virtual void greet() override 677 | { 678 | writer->write("Hello world!\n"); 679 | } 680 | }; 681 | 682 | Component getGreeterComponent() 683 | { 684 | return fruit::createComponent() 685 | .bind() 686 | .bind(); 687 | } 688 | 689 | int main() 690 | { 691 | Injector injector(getGreeterComponent()); 692 | Greeter* greeter = injector.get(); 693 | greeter->greet(); 694 | return 0; 695 | } 696 | 697 | 698 | == 3.2 泛型编程(GP) == 699 | 700 |

Boost.TypeTraits

701 | 702 | Docs:[http://boost.org/libs/type_traits] 703 | 704 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“类型特化”相关的辅助功能。 705 | 706 | == 3.3 函数式编程(FP) == 707 | 708 | (不了解“函数式编程”的同学,可以先看[https://zh.wikipedia.org/wiki/%E5%87%BD%E6%95%B8%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80 维基百科]) 709 | 710 |

Boost.Function

711 | 712 | Docs:[http://boost.org/libs/function] 713 | 714 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,用来辅助封装函数对象(仿函式)。 715 | 716 | 注:Boost 的这个子库已经进入 C++ 11 标准。 717 | 718 | 代码示例——封装标准 C 的函数 719 | 720 | #include 721 | #include 722 | #include 723 | #include 724 | 725 | using namespace std; 726 | 727 | boost::function f = atoi; 728 | cout << f("42") << '\n'; 729 | 730 | f = strlen; 731 | cout << f("42") << '\n'; 732 | 733 | 734 |

Boost.Lambda

735 | 736 | Docs:[http://boost.org/libs/lambda] 737 | 738 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“匿名函数/无名函数”的功能。 739 | 740 | 注:Boost 的这个子库已经进入 C++ 11 标准。 741 | 742 | 代码示例 743 | 744 | #include 745 | #include 746 | #include 747 | #include 748 | 749 | using namespace std; 750 | 751 | vector v; 752 | // 此处填充 v 753 | for_each(v.begin(), v.end(), cout << boost::lambda::_1 << "\n"); 754 | 755 | 756 |

simple_match

757 | 758 | Home:[https://github.com/jbandela/simple_match] 759 | 760 | 这个库是为了提供类似 Rust 语言中的 match 语法。 761 | 762 | (不懂 Rust 的同学,可以把 match 语法视作增强版的 switch/case) 763 | 764 | 代码示例 765 | 766 | #include 767 | #include 768 | using namespace simple_match; 769 | using namespace simple_match::placeholders; 770 | 771 | int x = 0; 772 | while (true) 773 | { 774 | std::cin >> x; 775 | match(x, 776 | 1, []() { std::cout << "one\n"; }, 777 | 2, []() { std::cout << "two\n"; }, 778 | _x < 10, [](auto&& n) { std::cout << n << " is less than 10\n"; }, 779 | 10 < _x < 20, [](auto&& n) { std::cout << n << " is between 10 and 20 exclusive\n"; }, 780 | _, []() { std::cout << "NOT match\n"; } 781 | ); 782 | } 783 | 784 | 785 | == 3.4 元编程(Metaprogramming) == 786 | 787 | (不知道何为“元编程”,可以先看[https://zh.wikipedia.org/wiki/%E5%85%83%E7%BC%96%E7%A8%8B 维基百科]) 788 | 789 |

Boost.MPL

790 | 791 | Docs:[http://boost.org/libs/mpl] 792 | 793 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“模板元编程”的框架。 794 | 795 |

Dlib

796 | 797 | Docs:[http://dlib.net/metaprogramming.html] 798 | 799 | Dlib 前面已经介绍过。它提供了“模板元编程”的辅助类。 800 | 801 | ---- 802 | 803 | = 4 调试 & 测试 = 804 | 805 | == 4.1 调试日志 == 806 | 807 |

Boost.Log

808 | 809 | Docs:[http://boost.org/libs/log] 810 | 811 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了记录日志的机制。 812 | 813 | 下面给出的示例是最简单的版本,其实它还提供了很丰富的扩展机制。 814 | 815 | 代码示例 816 | 817 | #include 818 | 819 | BOOST_LOG_TRIVIAL(debug) << "A debug severity message"; 820 | BOOST_LOG_TRIVIAL(info) << "An informational severity message"; 821 | 822 | 823 |

POCO.Logging

824 | 825 | Docs:[http://pocoproject.org/docs/package-Foundation.Logging.html] 826 | 827 | POCO 前面已经介绍过。它提供了好几个用于调试日志的封装类(包括特定于 Windows 平台和特定于 POSIX 平台的类)。 828 | 829 | 它还支持日志文件的循环存储。 830 | 831 |

Dlib

832 | 833 | Docs:[http://dlib.net/other.html#logger] 834 | 835 | Dlib 前面已经介绍过。它提供了风格类似 log4j 的日志记录机制。 836 | 837 | 代码示例 838 | 839 | #include 840 | #include 841 | 842 | using namespace dlib; 843 | 844 | logger dlog("example"); 845 | dlog.set_level(LALL); 846 | 847 | dlog << LINFO << "This is an informational message."; 848 | 849 | int variable = 8; 850 | dlog << LDEBUG << "The integer variable is set to " << variable; 851 | 852 | 853 |

wxWidgets

854 | 855 | Docs:[http://docs.wxwidgets.org/trunk/group__group__funcmacro__log.html] 856 | 857 | wxWidgets 前面已经介绍过。它提供了记录日志的函数和宏。 858 | 859 |

log4cpp

860 | 861 | Home:[http://log4cpp.sourceforge.net/] 862 | 863 | 如其名,这是一个模仿 log4j 的 C++ 库。支持多种操作系统(包括 Windows)。 864 | 865 | == 4.2 单元测试 == 866 | 867 |

Boost.Test

868 | 869 | Docs:[http://boost.org/libs/test] 870 | 871 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了与测试相关的各种辅助工具(包括单元测试)。 872 | 873 |

Google Test

874 | 875 | Home:[https://github.com/google/googletest] 876 | 877 | Links:[https://en.wikipedia.org/wiki/Google_Test Wikipedia] 878 | 879 | 这是 Google 提供的单元测试框架。从 Google Code 迁移到 GitHub 之后,又整合了 GoogleMock 项目。 880 | 881 | 一些知名的开源项目(Chromium、LLVM、OpenCV)用到了它。 882 | 883 |

CppUnit

884 | 885 | Home:[http://freedesktop.org/wiki/Software/cppunit/] 886 | 887 | Links:[https://en.wikipedia.org/wiki/CppUnit Wikipedia] 888 | 889 | 如其名,这是一个 C++ 的单元测试框架。该项目起先是作为 JUnit 的 C++ 移植而创建的。 890 | 891 |

Check

892 | 893 | Home:[http://check.sourceforge.net/] 894 | 895 | Links:[https://en.wikipedia.org/wiki/Check_%28unit_testing_framework%29 Wikipedia] 896 | 897 | 这是针对 C 的单元测试框架。 898 | 899 | 代码示例 900 | 901 | #include 902 | 903 | /* The basic unit test looks as follows: */ 904 | START_TEST (test_name) 905 | { 906 | /* unit test code */ 907 | } 908 | END_TEST 909 | /* The "START_TEST/END_TEST" pair are macros that setup basic structures to permit testing. 910 | It is a mistake to leave off the END_TEST marker; 911 | doing so produces all sorts of strange errors when the check is compiled. */ 912 | 913 | 914 | == 4.3 健壮性测试 == 915 | 916 |

Boost.Test.ExecutionMonitor

917 | 918 | Docs:[http://boost.org/libs/test/doc/html/execution-monitor.html] 919 | 920 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,它除了提供“单元测试”,还提供“内存泄漏的检测”。 921 | 922 | == 4.4 性能测试 == 923 | 924 |

benchmark

925 | 926 | Home:[https://github.com/google/benchmark] 927 | 928 | 这是 Google 提供的性能测试辅助工具,用来测试指定函数的执行时间。 929 | 930 | 它可以把测试结果导出为 CSV 或 JSON 格式。 931 | 932 | ---- 933 | 934 | = 5 操作系统 = 935 | 936 | == 5.1 跨操作系统 == 937 | 938 | === 5.1.1 文件系统 === 939 | 940 |

Boost.Filesystem

941 | 942 | Docs:[http://boost.org/libs/filesystem] 943 | 944 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了对“文件系统”的操作。 945 | 946 | 代码示例——获取文件大小 947 | 948 | #include 949 | #include 950 | 951 | int main(int argc, char* argv[]) 952 | { 953 | using namespace boost::filesystem; 954 | if(argc != 2) 955 | { 956 | std::cout << "Usage: \n" << argv[0] << " path\n"; 957 | return 1; 958 | } 959 | std::cout << argv[1] << " " << file_size(argv[1]) << '\n'; 960 | return 0; 961 | } 962 | 963 | 964 |

POCO.Filesystem

965 | 966 | Docs:[http://pocoproject.org/docs/package-Foundation.Filesystem.html] 967 | 968 | POCO 前面已经介绍过。它提供了文件系统相关的封装类(遍历目录和文件、通配符匹配、临时文件、文件变化通知...)。 969 | 970 |

wxWidgets

971 | 972 | Docs:[http://docs.wxwidgets.org/trunk/group__group__class__file.html] 973 | 974 | wxWidgets 前面已经介绍过。它提供了文件系统相关的封装类(遍历目录和文件、临时文件、文件变化通知...)。 975 | 976 |

APR

977 | 978 | Docs:[https://apr.apache.org/docs/apr/trunk/modules.html] 979 | 980 | APR 前面已经介绍过。它提供了“文件信息、文件名匹配”等功能。 981 | 982 | === 5.1.2 线程 === 983 | 984 |

Boost.Thread

985 | 986 | Docs:[http://boost.org/libs/thread] 987 | 988 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“多线程”的功能。 989 | 990 | 代码示例 991 | 992 | #include 993 | #include 994 | 995 | void hello_world() 996 | { 997 | std::cout << "Hello world, I'm a thread!\n"; 998 | } 999 | 1000 | int main() 1001 | { 1002 | boost::thread my_thread(&hello_world); // 启动一个线程 1003 | my_thread.join(); // 等待该线程结束 1004 | return 0; 1005 | } 1006 | 1007 | 1008 |

ACE

1009 | 1010 | Docs:[http://www.dre.vanderbilt.edu/Doxygen/Stable/libace-doc/annotated.html] 1011 | 1012 | ACE 前面已经介绍过。它提供了“多线程”的功能(参见文档中以“ACE_Thread”开头的类) 1013 | 1014 |

APR

1015 | 1016 | Docs:[https://apr.apache.org/docs/apr/trunk/modules.html] 1017 | 1018 | APR 前面已经介绍过。它提供了“线程池、线程同步/互斥”等功能,以及一些线程安全的数据结构。 1019 | 1020 |

POCO.Threading

1021 | 1022 | Docs:[http://pocoproject.org/docs/package-Foundation.Threading.html] 1023 | 1024 | POCO 前面已经介绍过。它提供了线程、线程池以及线程同步/互斥的封装类。 1025 | 1026 |

wxWidgets

1027 | 1028 | Docs:[http://docs.wxwidgets.org/trunk/group__group__class__threading.html] 1029 | 1030 | wxWidgets 前面已经介绍过。它提供了线程以及线程同步/互斥的封装类。 1031 | 1032 |

GNU Common C++

1033 | 1034 | Home:[http://www.gnu.org/software/commoncpp/] 1035 | 1036 | 由 GNU 提供的一套跨平台的线程并发框架。 1037 | 1038 | === 5.1.3 进程 === 1039 | 1040 |

ACE

1041 | 1042 | Docs:[http://www.dre.vanderbilt.edu/Doxygen/Stable/libace-doc/annotated.html] 1043 | 1044 | ACE 前面已经介绍过。它提供了“进程管理”的功能(参见文档中以“ACE_Process”开头的类)。 1045 | 1046 |

APR

1047 | 1048 | Docs:[https://apr.apache.org/docs/apr/trunk/modules.html] 1049 | 1050 | APR 前面已经介绍过。它提供了“进程管理”的功能。 1051 | 1052 |

POCO.Processes

1053 | 1054 | Docs:[http://pocoproject.org/docs/Poco.Process.html] 1055 | 1056 | POCO 前面已经介绍过。它提供了“进程”的封装类。 1057 | 1058 | === 5.1.4 本地进程间通信(IPC) === 1059 | 1060 | (本章节列举的是【本地】IPC,跨主机的网络通讯,参见本页面后续的章节) 1061 | 1062 |

Boost.Interprocess

1063 | 1064 | Docs:[http://boost.org/libs/interprocess] 1065 | 1066 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了共享内存和几种同步机制(Mutexes、Condition variables、Semaphores、Upgradable mutexes、File locks)。 1067 | 1068 |

ACE

1069 | 1070 | Docs:[http://www.dre.vanderbilt.edu/Doxygen/Stable/libace-doc/annotated.html] 1071 | 1072 | ACE 前面已经介绍过。它提供了许多种 IPC 机制(有些不是跨平台的)。 1073 | 1074 |

APR

1075 | 1076 | Docs:[https://apr.apache.org/docs/apr/trunk/modules.html] 1077 | 1078 | APR 前面已经介绍过。它提供了“进程同步、共享内存、信号处理”等功能。 1079 | 1080 |

POCO.Processes

1081 | 1082 | Docs:[http://pocoproject.org/docs/package-Foundation.Processes.html] 1083 | 1084 | POCO 前面已经介绍过。它提供了 IPC 相关的封装类(“共享内存”和“管道”)。 1085 | 1086 | == 5.2 特定于 Windows 系统 == 1087 | 1088 | === 5.2.1 注册表 === 1089 | 1090 |

wxWidgets

1091 | 1092 | Docs:[http://docs.wxwidgets.org/trunk/classwx_reg_key.html] 1093 | 1094 | wxWidgets 前面已经介绍过。它提供了操作 Windows 注册表的封装类。 1095 | 1096 |

POCO::Util

1097 | 1098 | Docs:[http://pocoproject.org/docs/Poco.Util.html] 1099 | 1100 | POCO 前面已经介绍过。它提供了操作 Windows 注册表的封装类(WinRegistryKey)。 1101 | 1102 | === 5.2.2 Windows 服务(Service) === 1103 | 1104 |

POCO::Util

1105 | 1106 | Docs:[http://pocoproject.org/docs/Poco.Util.html] 1107 | 1108 | POCO 前面已经介绍过。它提供了相应的封装类(WinService),可以用来操作 Service(注册、删除、启动、停止)。 1109 | 1110 | == 5.3 特定于 Linux & Unix 系统 == 1111 | 1112 | ---- 1113 | 1114 | = 6 图形用户界面(GUI) = 1115 | 1116 | == 6.1 GUI 框架 == 1117 | 1118 | === 6.1.1 跨平台的 GUI 框架 === 1119 | 1120 |

wxWidgets

1121 | 1122 | Docs:[http://docs.wxwidgets.org/trunk/modules.html] 1123 | 1124 | wxWidgets 前面已经介绍过。用 wxWidgets 开发 GUI 应用,其代码结构类似 MFC。熟悉 MFC 的程序员应该很容易上手。 1125 | 1126 | 代码示例——Hello world 1127 | 1128 | #include 1129 | #ifndef WX_PRECOMP 1130 | # include 1131 | #endif 1132 | 1133 | class MyApp: public wxApp 1134 | { 1135 | public: 1136 | virtual bool OnInit(); 1137 | }; 1138 | wxIMPLEMENT_APP(MyApp); 1139 | 1140 | class MyFrame: public wxFrame 1141 | { 1142 | public: 1143 | MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size); 1144 | private: 1145 | void OnExit(wxCommandEvent& event); 1146 | wxDECLARE_EVENT_TABLE(); 1147 | }; 1148 | wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) 1149 | EVT_MENU(wxID_EXIT, MyFrame::OnExit) 1150 | wxEND_EVENT_TABLE() 1151 | 1152 | bool MyApp::OnInit() 1153 | { 1154 | MyFrame* frame = new MyFrame("Hello, World", wxPoint(50, 50), wxSize(450, 340)); 1155 | frame->Show(true); 1156 | return true; 1157 | } 1158 | 1159 | MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) 1160 | : wxFrame(NULL, wxID_ANY, title, pos, size) 1161 | { 1162 | wxMenu* menuFile = new wxMenu(); 1163 | menuFile->Append(wxID_EXIT); 1164 | wxMenuBar* menuBar = new wxMenuBar(); 1165 | menuBar->Append(menuFile, "&File"); 1166 | SetMenuBar(menuBar); 1167 | } 1168 | 1169 | void MyFrame::OnExit(wxCommandEvent& event) 1170 | { 1171 | Close(true); 1172 | } 1173 | 1174 | 1175 |

Qt

1176 | 1177 | Qt 前面已经介绍过。下面给出一个 Hello world 的示例,让你看看 Qt 的风格。 1178 | 1179 | 代码示例——Hello world 1180 | 1181 | #include 1182 | #include 1183 | 1184 | int main(int argc, char* argv[]) 1185 | { 1186 | QApplication app(argc, argv); 1187 | QLabel label("Hello, world!"); 1188 | label.show(); 1189 | return app.exec(); 1190 | } 1191 | 1192 | 1193 |

GTK+

1194 | 1195 | Home:[http://www.gtk.org/] 1196 | 1197 | Links:[https://en.wikipedia.org/wiki/GTK%2B Wikipedia] [https://zh.wikipedia.org/wiki/GTK%2B 维基百科] 1198 | 1199 | 老牌的 GUI 框架,诞生于1998年。原先叫做“GIMP Toolkit”,是基于 C 开发的跨平台界面组件库。 1200 | 1201 | 代码示例——Hello world 1202 | 1203 | #include 1204 | 1205 | int main(int argc, char* argv[]) 1206 | { 1207 | gtk_init(&argc, &argv); 1208 | 1209 | GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 1210 | gtk_window_set_title(GTK_WINDOW(window), "Hello, world!"); 1211 | gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); 1212 | gtk_window_set_default_size(GTK_WINDOW(window), 200, 100); 1213 | 1214 | /* 1215 | ** Map the destroy signal of the window to gtk_main_quit; 1216 | ** When the window is about to be destroyed, we get a notification and 1217 | ** stop the main GTK+ loop by returning 0 1218 | */ 1219 | g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); 1220 | 1221 | gtk_widget_show_all(window); 1222 | 1223 | /* Start the main loop, do nothing until the application is closed */ 1224 | gtk_main(); 1225 | 1226 | return 0; 1227 | } 1228 | 1229 | 1230 |

FLTK

1231 | 1232 | Home:[http://www.fltk.org/] 1233 | 1234 | Links:[https://en.wikipedia.org/wiki/FLTK Wikipedia] [https://zh.wikipedia.org/wiki/FLTK 维基百科] 1235 | 1236 | 它的全称是“Fast, Light Toolkit”。如其名,它非常轻量级。用它写一个“Hello World 应用”,静态链接后大约才 100KB 1237 | 1238 | 代码示例——Hello world 1239 | 1240 | #include 1241 | #include 1242 | #include 1243 | 1244 | int main(int argc, char **argv) 1245 | { 1246 | Fl_Window* window = new Fl_Window(300, 180); 1247 | Fl_Box* box = new Fl_Box(20, 40, 260, 100, "Hello, World!"); 1248 | box->box(FL_UP_BOX); 1249 | box->labelsize(36); 1250 | box->labelfont(FL_BOLD+FL_ITALIC); 1251 | box->labeltype(FL_SHADOW_LABEL); 1252 | 1253 | window->end(); 1254 | window->show(argc, argv); 1255 | return Fl::run(); 1256 | } 1257 | 1258 | 1259 | === 6.1.2 特定于 Windows 的 GUI 框架 === 1260 | 1261 |

WTL(Windows Template Library)

1262 | 1263 | Home:[http://sourceforge.net/projects/wtl/] 1264 | 1265 | Links:[https://en.wikipedia.org/wiki/Windows_Template_Library Wikipedia] [https://zh.wikipedia.org/wiki/Windows_Template_Library 维基百科] 1266 | 1267 | 这是微软雇员 Nenad Stefanovic 开发的开源 GUI 框架。开发 WTL 是为了提供一个轻量级的 MFC 替代品。 1268 | 1269 | == 6.2 图表(Chart) == 1270 | 1271 |

Qt

1272 | 1273 | Docs:[http://doc.qt.io/QtCharts/] 1274 | 1275 | Qt 前面已经介绍过。它内置了一套 Chart 的封装类。 1276 | 1277 | 代码示例——饼图 1278 | 1279 | #include 1280 | #include 1281 | #include 1282 | #include 1283 | #include 1284 | 1285 | QT_CHARTS_USE_NAMESPACE 1286 | 1287 | int main(int argc, char* argv[]) 1288 | { 1289 | QApplication app(argc, argv); 1290 | 1291 | QPieSeries* series = new QPieSeries(); 1292 | series->append("Jane", 1); 1293 | series->append("Joe", 2); 1294 | series->append("Andy", 3); 1295 | series->append("Barbara", 4); 1296 | series->append("Axel", 5); 1297 | 1298 | QPieSlice* slice = series->slices().at(1); 1299 | slice->setExploded(); 1300 | slice->setLabelVisible(); 1301 | slice->setPen(QPen(Qt::darkGreen, 2)); 1302 | slice->setBrush(Qt::green); 1303 | 1304 | QChart* chart = new QChart(); 1305 | chart->addSeries(series); 1306 | chart->setTitle("Simple piechart example"); 1307 | chart->legend()->hide(); 1308 | 1309 | QChartView* chartView = new QChartView(chart); 1310 | chartView->setRenderHint(QPainter::Antialiasing); 1311 | 1312 | QMainWindow window; 1313 | window.setCentralWidget(chartView); 1314 | window.resize(400, 300); 1315 | window.show(); 1316 | 1317 | return app.exec(); 1318 | } 1319 | 1320 | 1321 |

wxCode

1322 | 1323 | Home:[http://wxcode.sourceforge.net/] 1324 | 1325 | 该项目专门提供组件来扩展 wxWidgets 的功能。它里面提供了好几种图表的组件(wxChart、wxFreeChart、wxPlotCtrl)。 1326 | 1327 |

wxMathPlot

1328 | 1329 | Home:[http://wxmathplot.sourceforge.net/] 1330 | 1331 | 看名称就知道它是跟 wxWidgets 搭配的。效果图参见“[http://wxmathplot.sourceforge.net/screenshot.shtml 这里]” 1332 | 1333 | == 6.3 文本编辑 == 1334 | 1335 |

Scintilla

1336 | 1337 | Home:[https://scintilla.org/] 1338 | 1339 | Links:[https://en.wikipedia.org/wiki/Scintilla_(software) Wikipedia] 1340 | 1341 | 功能【超强】的文本编辑组件,支持:词法高亮、代码折叠、自动补全、动态提示......(基本上你能想到的,它都已经有了) 1342 | 1343 | 不光功能齐全,还支持各种主流的操作系统平台。很多编辑器/IDE 用到它。 1344 | 1345 | ---- 1346 | 1347 | = 7 文本用户界面(TUI) = 1348 | 1349 | == 7.1 命令行参数 == 1350 | 1351 |

getopt

1352 | 1353 | Home:[https://www.gnu.org/software/libc/manual/html_node/Getopt.html] 1354 | 1355 | Links:[https://en.wikipedia.org/wiki/Getopt Wikipedia] 1356 | 1357 | 这是标准C用来处理命令行参数的老牌函数,诞生于上世纪80年代初期。 1358 | 1359 | 它有很多种不同的实现,如今用得最多的是 GNU C Library 的实现。GNU 还实现了一个增强版 getopt_long。 1360 | 1361 | 代码示例 1362 | 1363 | #include /* for printf */ 1364 | #include /* for exit */ 1365 | #include /* for getopt */ 1366 | 1367 | int main(int argc, char* argv[]) 1368 | { 1369 | int digit_optind = 0; 1370 | int aopt = 0, bopt = 0; 1371 | char* copt = NULL; 1372 | char* dopt = NULL; 1373 | int c; 1374 | while( (c = getopt(argc, argv, "abc:d:012")) != -1) 1375 | { 1376 | int this_option_optind = optind ? optind : 1; 1377 | switch(c) 1378 | { 1379 | case '0': 1380 | case '1': 1381 | case '2': 1382 | if(digit_optind != 0 && digit_optind != this_option_optind) 1383 | { 1384 | printf("digits occur in two different argv-elements.\n"); 1385 | } 1386 | digit_optind = this_option_optind; 1387 | printf("option %c\n", c); 1388 | break; 1389 | case 'a': 1390 | printf("option a\n"); 1391 | aopt = 1; 1392 | break; 1393 | case 'b': 1394 | printf("option b\n"); 1395 | bopt = 1; 1396 | break; 1397 | case 'c': 1398 | printf("option c with value '%s'\n", optarg); 1399 | copt = optarg; 1400 | break; 1401 | case 'd': 1402 | printf("option d with value '%s'\n", optarg); 1403 | dopt = optarg; 1404 | break; 1405 | case '?': 1406 | break; 1407 | default: 1408 | printf("?? getopt returned character code 0%o ??\n", c); 1409 | } 1410 | } 1411 | if(optind < argc) 1412 | { 1413 | printf("non-option ARGV-elements: "); 1414 | while(optind < argc) 1415 | { 1416 | printf("%s ", argv[optind++]); 1417 | } 1418 | printf("\n"); 1419 | } 1420 | exit (0); 1421 | } 1422 | 1423 | 1424 |

Boost.Program_options

1425 | 1426 | Docs:[http://boost.org/libs/program_options] 1427 | 1428 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“处理命令行参数”的功能。 1429 | 1430 | 它的功能很丰富,但是比较重型。 1431 | 1432 |

docopt

1433 | 1434 | Home:[https://github.com/docopt/docopt.cpp] 1435 | 1436 | 这是一个很有创意的库,提供了一种【全新】的方式来处理命令行参数。 1437 | 1438 | 你只需定义好命令行的帮助文本(usage),该库会根据 usage 文本自动分析出命令行参数的定义。 1439 | 1440 | 也就是说:用了这个库,就无需再写一大堆 parse 命令行参数的代码 :) 1441 | 1442 | 代码示例 1443 | 1444 | #include 1445 | #include 1446 | 1447 | static const char USAGE[] = 1448 | R"(Naval Fate. 1449 | 1450 | Usage: 1451 | naval_fate ship new ... 1452 | naval_fate ship move [--speed=] 1453 | naval_fate ship shoot 1454 | naval_fate mine (set|remove) [--moored | --drifting] 1455 | naval_fate (-h | --help) 1456 | naval_fate --version 1457 | 1458 | Options: 1459 | -h --help Show this screen. 1460 | --version Show version. 1461 | --speed= Speed in knots [default: 10]. 1462 | --moored Moored (anchored) mine. 1463 | --drifting Drifting mine. 1464 | )"; 1465 | 1466 | int main(int argc, const char* argv[]) 1467 | { 1468 | std::map args 1469 | = docopt::docopt(USAGE, 1470 | { argv + 1, argv + argc }, 1471 | true, // 是否显示帮助 1472 | "Naval Fate 2.0"); // 版本号 1473 | 1474 | for(auto const& arg : args) 1475 | { 1476 | std::cout << arg.first << arg.second << std::endl; 1477 | } 1478 | 1479 | return 0; 1480 | } 1481 | 1482 | 1483 | == 7.2 文本终端 == 1484 | 1485 |

ncurses

1486 | 1487 | Home:[https://www.gnu.org/software/ncurses/] 1488 | 1489 | Links:[https://en.wikipedia.org/wiki/Ncurses Wikipedia] [https://zh.wikipedia.org/wiki/Ncurses 维基百科] 1490 | 1491 | ncurses 是“new curses”的缩略词,它是 [https://en.wikipedia.org/wiki/Curses_(programming_library) curses] 库的自由软件克隆,诞生于1993年。 1492 | 1493 | 大名鼎鼎的 [https://en.wikipedia.org/wiki/Eric_S._Raymond Eric S. Raymond] 曾参与早期版本的开发。 1494 | 1495 | = 8 网络 = 1496 | 1497 | == 8.1 链路层 & 网络层 == 1498 | 1499 |

libpcap

1500 | 1501 | Home:[http://www.tcpdump.org/] 1502 | 1503 | Links:[https://en.wikipedia.org/wiki/Pcap Wikipedia] 1504 | 1505 | 很著名的 Sniffer 抓包库,基于 C 语言开发。 1506 | 1507 | 代码示例——一个简单的抓包示例 1508 | 1509 | #include 1510 | #include 1511 | 1512 | int main() 1513 | { 1514 | pcap_t* handle; /* Session handle */ 1515 | char* dev; /* The device to sniff on */ 1516 | char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */ 1517 | struct bpf_program fp; /* The compiled filter */ 1518 | char filter_exp[] = "port 23"; /* The filter expression */ 1519 | bpf_u_int32 mask; /* Our netmask */ 1520 | bpf_u_int32 net; /* Our IP */ 1521 | struct pcap_pkthdr header; /* The header that pcap gives us */ 1522 | const u_char* packet; /* The actual packet */ 1523 | 1524 | /* Define the device */ 1525 | dev = pcap_lookupdev(errbuf); 1526 | if(dev == NULL) 1527 | { 1528 | fprintf(stderr, "Couldn't find default device: %s\n", errbuf); 1529 | return 2; 1530 | } 1531 | /* Find the properties for the device */ 1532 | if(pcap_lookupnet(dev, &net, &mask, errbuf) == -1) 1533 | { 1534 | fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf); 1535 | net = 0; 1536 | mask = 0; 1537 | } 1538 | /* Open the session in promiscuous mode */ 1539 | handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf); 1540 | if(handle == NULL) 1541 | { 1542 | fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); 1543 | return 2; 1544 | } 1545 | /* Compile and apply the filter */ 1546 | if(pcap_compile(handle, &fp, filter_exp, 0, net) == -1) 1547 | { 1548 | fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); 1549 | return 2; 1550 | } 1551 | if(pcap_setfilter(handle, &fp) == -1) 1552 | { 1553 | fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle)); 1554 | return 2; 1555 | } 1556 | 1557 | packet = pcap_next(handle, &header); /* Grab a packet */ 1558 | printf("Jacked a packet with length of [%d]\n", header.len); 1559 | pcap_close(handle); /* Close the session */ 1560 | return 0; 1561 | } 1562 | 1563 | 1564 |

WinPcap

1565 | 1566 | Home:[http://www.winpcap.org/] 1567 | 1568 | Links:[https://en.wikipedia.org/wiki/Pcap Wikipedia] 1569 | 1570 | 它是 libpcap 在 Windows 系统下的移植。 1571 | 1572 | == 8.2 传输层 == 1573 | 1574 |

socket

1575 | 1576 | socket 最早源自 BSD 系统,有时候也称“伯克利套接字”。 1577 | 1578 | 它已成了传输层网络编程的标准,主流的操作系统平台都支持,主流的 C/C++ 编译器也都内置了相关的库文件。 1579 | 1580 |

ACE

1581 | 1582 | Docs:[http://www.dre.vanderbilt.edu/Doxygen/Stable/libace-doc/annotated.html] 1583 | 1584 | ACE 前面已经介绍过。它提供了针对 socket 的更高层封装。 1585 | 1586 |

APR

1587 | 1588 | Docs:[https://apr.apache.org/docs/apr/trunk/modules.html] 1589 | 1590 | APR 前面已经介绍过。它提供了对 socket 的封装和增强。 1591 | 1592 |

POCO::Net

1593 | 1594 | Docs:[http://pocoproject.org/docs/Poco.Net.html] 1595 | 1596 | POCO 前面已经介绍过。它提供了针对 TCP 服务端的封装类。 1597 | 1598 | == 8.3 标准的应用层 == 1599 | 1600 | === 8.3.1 综合性的库 === 1601 | 1602 |

cURL & libcurl

1603 | 1604 | Home:[http://curl.haxx.se/libcurl/] 1605 | 1606 | Links:[https://en.wikipedia.org/wiki/CURL Wikipedia] [https://zh.wikipedia.org/wiki/CURL 维基百科] 1607 | 1608 | cURL 是一个功能很强的网络库/网络工具,支持 N 多应用层协议。下面是支持协议的列表(从它官网抄袭的) 1609 | 1610 | DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMTP, SMTPS, Telnet and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, HTTP/2 1611 | 1612 | 它采用 C 语言开发,开发很活跃,支持非常多的操作系统平台。 1613 | 1614 | 关于 cURL,俺前几年写过一篇博文推荐它(在“[http://program-think.blogspot.com/2009/03/opensource-review-curl-library.html 这里]”)。 1615 | 1616 | 代码示例——IMAP 协议(邮件) 1617 | 1618 | #include 1619 | #include 1620 | 1621 | int main() 1622 | { 1623 | curl_global_init(CURL_GLOBAL_ALL); 1624 | 1625 | CURL* curl = curl_easy_init(); 1626 | if(curl) 1627 | { 1628 | curl_easy_setopt(curl, CURLOPT_USERNAME, "user"); 1629 | curl_easy_setopt(curl, CURLOPT_PASSWORD, "password"); 1630 | 1631 | // This will list the folders within the user's mailbox. If you want to 1632 | // list the folders within a specific folder, for example the inbox, 1633 | // then specify the folder as a path in the URL such as /INBOX 1634 | curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com"); 1635 | 1636 | CURLcode res = curl_easy_perform(curl); 1637 | if(res != CURLE_OK) // Check for errors 1638 | { 1639 | fprintf(stderr, "curl_easy_perform() failed: %s\n", 1640 | curl_easy_strerror(res)); 1641 | } 1642 | 1643 | curl_easy_cleanup(curl); // Always cleanup 1644 | } 1645 | 1646 | curl_global_cleanup(); 1647 | return 0; 1648 | } 1649 | 1650 | 1651 |

cURLpp

1652 | 1653 | Home:[http://www.curlpp.org/] 1654 | 1655 | 看名字就知道这是 cURL 的 C++ 封装。 1656 | 1657 |

POCO::Net

1658 | 1659 | Docs:[http://pocoproject.org/docs/Poco.Net.html] 1660 | 1661 | POCO 前面已经介绍过。它提供了几种常见应用层协议(HTTP、SMTP、POP3、FTP、NTP ...)的封装类。 1662 | 1663 | === 8.3.2 HTTP === 1664 | 1665 | (关于“HTTP 协议”,请参见另一个大类:“Web 相关”) 1666 | 1667 | === 8.3.3 DNS === 1668 | 1669 |

c-ares

1670 | 1671 | Home:[http://c-ares.haxx.se/] 1672 | 1673 | 这是一个 C 语言开发的 DNS 封装库,支持异步 DNS 请求,跨多种操作系统。 1674 | 1675 | 对比官网域名可知,它跟 cURL 是一家子。除了 cURL/libcurl 用到它,还有一些知名开源项目(比如:Wireshark、node.js ...)用到它。 1676 | 1677 | === 8.3.4 XMPP === 1678 | 1679 | ([https://zh.wikipedia.org/wiki/XMPP XMPP] 的洋文全称是“Extensible Messaging and Presence Protocol”。这是一个标准化的 IM 交互协议) 1680 | 1681 |

Swiften

1682 | 1683 | Home:[http://swift.im/swiften.html] 1684 | 1685 | 这是一个 C++ 语言开发的 XMPP 封装库。它同时也是 Swift 聊天客户端所用的后端。 1686 | 1687 | 它大量使用了 Boost 的子库(Signal、Bind、Optional、Smart Pointers ...)。 1688 | 1689 |

QXmpp

1690 | 1691 | Home:[https://github.com/qxmpp-project/qxmpp] 1692 | 1693 | 这是一个 C++ 语言开发的 XMPP 封装库。从它的名称可以看出——依赖了 Qt 框架(需要 Qt 4.5 或更高版本)。 1694 | 1695 | == 8.4 自定义的应用层 == 1696 | 1697 |

Protocol Buffers

1698 | 1699 | Home:[https://developers.google.com/protocol-buffers/] 1700 | 1701 | Links:[https://en.wikipedia.org/wiki/Protocol_Buffers Wikipedia] 1702 | 1703 | 它是 Google 开发的一个跨语言的库,用于传输业务数据时的“编码/解码”。其优点是:跨多种语言、高性能、向前兼容、向后兼容。 1704 | 1705 | 具体的使用,可以参考俺前几年写过的一篇博文(在“[http://program-think.blogspot.com/2009/05/opensource-review-protocol-buffers.html 这里]”)。 1706 | 1707 | 作为 Protocol Buffers 的发明者,Google 默认实现了三种编程语言(C++、Java、Python)对它的支持。除了 Google 官方提供的这三种语言,它还支持很多其它的编程语言(由第三方提供)。 1708 | 1709 |

Apache Thrift

1710 | 1711 | Home:[https://thrift.apache.org/] 1712 | 1713 | Links:[https://en.wikipedia.org/wiki/Apache_Thrift Wikipedia] 1714 | 1715 | 来自于 Apache 社区,提供了一种跨语言的通讯机制。 1716 | 1717 | 程序员通过 Thrift 的“接口定义语言”定义通讯协议格式,然后 Thrift 根据协议格式自动帮你生成服务端和客户端代码。 1718 | 1719 | (在这个方面,它有点类似于 Google 的 Protocol Buffers) 1720 | 1721 | == 8.5 网络库、框架、中间件 == 1722 | 1723 |

Boost.Asio

1724 | 1725 | Docs:[http://boost.org/libs/asio] 1726 | 1727 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了异步网络通讯和异步 I/O。 1728 | 1729 | 代码示例——TCP Server 1730 | 1731 | #include 1732 | #include 1733 | #include 1734 | 1735 | int main() 1736 | { 1737 | using boost::asio::ip::tcp; 1738 | try 1739 | { 1740 | boost::asio::io_service io_service; 1741 | tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13)); 1742 | while(true) 1743 | { 1744 | tcp::socket socket(io_service); 1745 | acceptor.accept(socket); 1746 | 1747 | std::string msg = "Hello, world"; 1748 | boost::system::error_code ignored_err; 1749 | boost::asio::write(socket, boost::asio::buffer(msg), ignored_err); 1750 | } 1751 | } 1752 | catch(std::exception& err) 1753 | { 1754 | std::cerr << err.what() << std::endl; 1755 | } 1756 | return 0; 1757 | } 1758 | 1759 | 1760 |

ACE

1761 | 1762 | Docs:[http://www.dre.vanderbilt.edu/Doxygen/Stable/libace-doc/annotated.html] 1763 | 1764 | ACE 前面已经介绍过。它提供了很多种用于网络通讯的设计模式。 1765 | 1766 |

ZeroMQ(ØMQ)

1767 | 1768 | Home:[http://www.zeromq.org/] 1769 | 1770 | Links:[https://en.wikipedia.org/wiki/ZeroMQ Wikipedia] [https://zh.wikipedia.org/wiki/%C3%98MQ 维基百科] 1771 | 1772 | ZeroMQ 是一个轻量级、跨平台的开源库,提供了高性能、异步的消息队列。采用 C++ 开发,提供了多种语言的绑定。 1773 | 1774 | 与传统的消息中间件不同,使用 ZeroMQ 不需要额外的“消息代理(message broker)”。 1775 | 1776 | 俺曾经写过一篇博文推荐它(在“[http://program-think.blogspot.com/2011/08/opensource-review-zeromq.html 这里]”)。 1777 | 1778 | 代码示例——TCP Server 1779 | 1780 | #include 1781 | 1782 | int main() 1783 | { 1784 | zmq::context_t context(1); 1785 | 1786 | zmq::socket_t responder(context, ZMQ_REP); 1787 | responder.connect("tcp://localhost:5560"); 1788 | 1789 | while(true) 1790 | { 1791 | // Wait for next request from client 1792 | std::string request = s_recv(responder); 1793 | std::cout << "Received request: " << request << std::endl; 1794 | 1795 | // Do some 'work' 1796 | sleep(1); 1797 | 1798 | // Send reply back to client 1799 | s_send(responder, "Hello, world"); 1800 | } 1801 | } 1802 | 1803 | 1804 |

nanomsg

1805 | 1806 | Home:[http://nanomsg.org/] 1807 | 1808 | 很类似 ZeroMQ 的库,比 ZMQ 更加轻量级。采用 C 开发,提供了多种语言的绑定。 1809 | 1810 | API 完全参照 BSD socket 的风格和语义。 1811 | 1812 | 代码示例——Request/Reply 1813 | 1814 | #include 1815 | #include 1816 | #include 1817 | #include 1818 | #include 1819 | 1820 | int reply(const char* url) 1821 | { 1822 | int sock = nn_socket(AF_SP, NN_PULL); 1823 | assert(sock >= 0); 1824 | assert(nn_bind(sock, url) >= 0); 1825 | while(1) 1826 | { 1827 | char* msg = NULL; 1828 | int bytes = nn_recv(sock, &msg, NN_MSG, 0); 1829 | assert(bytes >= 0); 1830 | printf("RECEIVED:\n%s\n", msg); 1831 | nn_freemsg(msg); 1832 | } 1833 | } 1834 | 1835 | int request(const char* url, const char* msg) 1836 | { 1837 | int sz_msg = strlen(msg) + 1; // '\0' 1838 | int sock = nn_socket(AF_SP, NN_PUSH); 1839 | assert(sock >= 0); 1840 | assert(nn_connect(sock, url) >= 0); 1841 | printf("SENDING:\n%s\n", msg); 1842 | int bytes = nn_send(sock, msg, sz_msg, 0); 1843 | assert(bytes == sz_msg); 1844 | return nn_shutdown(sock, 0); 1845 | } 1846 | 1847 | 1848 |

ICE(Internet Communications Engine)

1849 | 1850 | Home:[https://zeroc.com/] 1851 | 1852 | Links:[https://en.wikipedia.org/wiki/Internet_Communications_Engine Wikipedia] [https://zh.wikipedia.org/wiki/ICE_(%E4%B8%AD%E9%97%B4%E4%BB%B6) 维基百科] 1853 | 1854 | 这是一个面向对象的通讯中间件,诞生于2002年。支持不同编程语言的通讯。 1855 | 1856 | 它的设计借鉴了 CORBA,好在没有 CORBA 那么复杂。 1857 | 1858 |

libevent

1859 | 1860 | Home:[http://libevent.org/] 1861 | 1862 | Links:[https://en.wikipedia.org/wiki/Libevent Wikipedia] [https://zh.wikipedia.org/wiki/Libevent 维基百科] 1863 | 1864 | 它提供了异步事件处理机制。在网络开发中,可以用它替代传统的“event loop”,有助于简化代码。 1865 | 1866 | 它被一些知名的开源项目使用(比如:[https://zh.wikipedia.org/wiki/Tor Tor]、[https://zh.wikipedia.org/wiki/Memcached memcached])。 1867 | 1868 | 代码示例——HTTP Server(本示例基于 ANSI C) 1869 | 1870 | #include 1871 | #include 1872 | #include 1873 | #include 1874 | #include 1875 | #include 1876 | 1877 | void generic_request_handler(struct evhttp_request* req, void* arg) 1878 | { 1879 | struct evbuffer* return_buffer = evbuffer_new(); 1880 | 1881 | evbuffer_add_printf(return_buffer, "Thanks for the request!"); 1882 | evhttp_send_reply(req, HTTP_OK, "Client", return_buffer); 1883 | evbuffer_free(return_buffer); 1884 | } 1885 | 1886 | int main() 1887 | { 1888 | short http_port = 8080; 1889 | char* http_addr = "127.0.0.1"; 1890 | struct evhttp* http_server = NULL; 1891 | 1892 | event_init(); 1893 | http_server = evhttp_start(http_addr, http_port); 1894 | evhttp_set_gencb(http_server, generic_request_handler, NULL); 1895 | 1896 | fprintf(stderr, "Server started on port %d\n", http_port); 1897 | event_dispatch(); 1898 | 1899 | return 0; 1900 | } 1901 | 1902 | 1903 | 代码示例——HTTP Server(本示例基于 C++ 11 标准) 1904 | 1905 | #include 1906 | #include 1907 | #include 1908 | #include 1909 | 1910 | int main() 1911 | { 1912 | if(!event_init()) 1913 | { 1914 | std::cerr << "Failed to init libevent." << std::endl; 1915 | return -1; 1916 | } 1917 | char const SrvAddress[] = "127.0.0.1"; 1918 | std::uint16_t SrvPort = 8080; 1919 | std::unique_ptr Server(evhttp_start(SrvAddress, SrvPort), &evhttp_free); 1920 | if(!Server) 1921 | { 1922 | std::cerr << "Failed to init http server." << std::endl; 1923 | return -1; 1924 | } 1925 | 1926 | void (*OnReq)(evhttp_request* req, void*) = [] (evhttp_request* req, void*) 1927 | { 1928 | auto* OutBuf = evhttp_request_get_output_buffer(req); 1929 | if(!OutBuf) 1930 | { 1931 | return; 1932 | } 1933 | evbuffer_add_printf(OutBuf, "

Hello, World!

"); 1934 | evhttp_send_reply(req, HTTP_OK, "", OutBuf); 1935 | }; 1936 | 1937 | evhttp_set_gencb(Server.get(), OnReq, nullptr); 1938 | if(event_dispatch() == -1) 1939 | { 1940 | std::cerr << "Failed to run messahe loop." << std::endl; 1941 | return -1; 1942 | } 1943 | return 0; 1944 | } 1945 | 1946 | 1947 |

libev

1948 | 1949 | Home:[http://libev.schmorp.de/] 1950 | 1951 | 看名称就能猜到它跟 libevent 很像。实际上,你可以把 libev 视为 libevent 的竞争性替代品。 1952 | 1953 | [http://www.gevent.org/ gevent] 官方博客的[http://blog.gevent.org/2011/04/28/libev-and-libevent/ 一篇文章]对比了这俩库的优缺点。 1954 | 1955 |

libuv

1956 | 1957 | Home:[https://github.com/libuv/libuv] 1958 | 1959 | Links:[https://en.wikipedia.org/wiki/Libuv Wikipedia] 1960 | 1961 | 它提供了跨平台的异步 I/O 机制。主要是为了提供给 [https://en.wikipedia.org/wiki/Node.js Node.js] 使用。 1962 | 1963 | 除了支持网络通讯,还支持:线程池、Windows 命名管道、Unix domain sockets、文件系统事件通知 ...... 1964 | 1965 |

Dlib

1966 | 1967 | Docs:[http://dlib.net/network.html] 1968 | 1969 | Dlib 前面已经介绍过。它针对网络通讯,提供了比较高的抽象层。 1970 | 1971 | ---- 1972 | 1973 | = 9 数据库 = 1974 | 1975 | == 9.1 开源数据库 == 1976 | 1977 |

MySQL

1978 | 1979 | Home:[https://www.mysql.com/] 1980 | 1981 | Links:[https://en.wikipedia.org/wiki/MySQL Wikipedia] [https://zh.wikipedia.org/wiki/MySQL 维基百科] 1982 | 1983 | 名气最大的开源数据库,诞生于1995年,采用 C 和 C++ 语言开发。如今隶属于 Oracle 公司。 1984 | 1985 |

PostgreSQL

1986 | 1987 | Home:[http://postgresql.org/] 1988 | 1989 | Links:[https://en.wikipedia.org/wiki/PostgreSQL Wikipedia] [https://zh.wikipedia.org/wiki/PostgreSQL 维基百科] 1990 | 1991 | 名气仅次于 MySQL 的开源数据库,诞生于1996年。采用 C 语言开发。 1992 | 1993 |

SQLite

1994 | 1995 | Home:[http://sqlite.org/] 1996 | 1997 | Links:[https://en.wikipedia.org/wiki/SQLite Wikipedia] [https://zh.wikipedia.org/wiki/SQLite 维基百科] 1998 | 1999 | 它是一个很优秀的嵌入式(进程内)数据库,非常轻量级,支持各种作系统平台。采用 C 语言开发。 2000 | 2001 | 俺前几年写过一篇博文推荐它(在“[http://program-think.blogspot.com/2009/04/how-to-use-sqlite.html 这里]”)。 2002 | 2003 |

MongoDB

2004 | 2005 | Home:[https://www.mongodb.org/] 2006 | 2007 | Links:[https://en.wikipedia.org/wiki/MongoDB Wikipedia] 2008 | 2009 | 这是近几年兴起的 NoSQL 数据库的一员。它本身是基于 C++ 和 C 开发的。 2010 | 2011 |

Redis

2012 | 2013 | Home:[http://redis.io/] 2014 | 2015 | Links:[https://zh.wikipedia.org/wiki/Redis 维基百科] [https://en.wikipedia.org/wiki/Redis Wikipedia] 2016 | 2017 | 诞生于2009年,是目前(2014~2015)最流行的键值存储数据库,基于 C 语言开发。 2018 | 2019 | 以性能高而著称,很多大型网站用到它(Twitter、GitHub、Flickr、Instagram、百度、新浪、腾讯、搜狐) 2020 | 2021 |

Berkeley DB(BDB)

2022 | 2023 | Home:[http://www.oracle.com/us/products/database/berkeley-db/] 2024 | 2025 | Links:[https://en.wikipedia.org/wiki/Berkeley_DB Wikipedia] [https://zh.wikipedia.org/wiki/Berkeley_DB 维基百科] 2026 | 2027 | 诞生于1994年,是一个很老牌的嵌入式(进程内)数据库,提供“键值存储”的功能,基于 C 语言开发。 2028 | 2029 | 开发 BDB 的公司于2006年被 Oracle 收购。 2030 | 2031 | 很多开源项目用到它。甚至 MySQL 也包含了一个基于 BDB 的存储后端。 2032 | 2033 |

LevelDB

2034 | 2035 | Home:[https://github.com/google/leveldb] 2036 | 2037 | Links:[https://en.wikipedia.org/wiki/LevelDB Wikipedia] [https://zh.wikipedia.org/wiki/LevelDB 维基百科] 2038 | 2039 | 它是 Google 基于 C++ 开发的 NoSQL 数据库,提供“键值存储”的功能。 2040 | 2041 | 号称速度很快,内置数据压缩(基于 [https://en.wikipedia.org/wiki/Snappy_(software) Snappy] 库)。 2042 | 2043 | 比特币项目用到它。Facebook 基于它开发出 RocksDB 数据库。 2044 | 2045 |

Firebird

2046 | 2047 | Home:[http://www.firebirdsql.org/] 2048 | 2049 | Links:[https://en.wikipedia.org/wiki/Firebird_%28database_server%29 Wikipedia] [https://zh.wikipedia.org/wiki/Firebird_(%E6%95%B0%E6%8D%AE%E5%BA%93) 维基百科] 2050 | 2051 | 它是2000年的时候,从 [https://en.wikipedia.org/wiki/Borland Borland] 公司的 InterBase 数据库派生出来的。 2052 | 2053 | 基于 C++ 开发,支持多种操作系统平台。 2054 | 2055 | 关于它有个插曲:Firefox 浏览器曾经用过“Firebird”这个名称,因为跟 Firebird 数据库同名,后来才改用 Firefox 这个名称。 2056 | 2057 |

ScyllaDB

2058 | 2059 | Home:[http://www.scylladb.com/] 2060 | 2061 | 这是2015年新兴的 NoSQL 数据库,相当于是用 C++ 重写了(Java 开发的)Cassandra。 2062 | 2063 | 号称性能提高10倍,并且延迟极低。 2064 | 2065 | == 9.2 数据库 API 的封装库 == 2066 | 2067 | === 9.2.1 综合性的封装库 === 2068 | 2069 |

OTL

2070 | 2071 | Home:[http://otl.sourceforge.net/] 2072 | 2073 | Links:[https://en.wikipedia.org/wiki/Oracle_Template_Library Wikipedia] 2074 | 2075 | 原生支持的数据库:Oracle、SQL Server、DB2、Informix、TimesTen, MAX/DB;另支持 ODBC。 2076 | 2077 | 它的特色是:全部代码都在一个头文件中。 2078 | 2079 | 代码示例——操作 Oracle 数据库 2080 | 2081 | #include 2082 | #include 2083 | 2084 | #define OTL_ORA8 // Compile OTL 4.0/OCI8 2085 | #include // include the OTL 4.0 header file 2086 | 2087 | int main() 2088 | { 2089 | otl_connect::otl_initialize(); 2090 | try 2091 | { 2092 | otl_connect db; 2093 | db.rlogon("scott/tiger"); // connect to Oracle 2094 | otl_cursor::direct_exec( 2095 | db, 2096 | "drop table test_tab", 2097 | otl_exception::disabled // disable OTL exceptions 2098 | ); 2099 | 2100 | otl_cursor::direct_exec( 2101 | db, 2102 | "create table test_tab(f1 number, f2 varchar2(30))" 2103 | ); 2104 | } 2105 | catch(otl_exception& err) 2106 | { 2107 | using namespace std; 2108 | // intercept OTL exceptions 2109 | cerr << err.msg << endl; // print error message 2110 | cerr << err.stm_text << endl; // print SQL that caused the error 2111 | cerr << err.var_info << endl; // print variable that caused the error 2112 | } 2113 | 2114 | db.logoff(); // disconnect from Oracle 2115 | return 0; 2116 | } 2117 | 2118 | 2119 | === 9.2.2 MySQL 封装库 === 2120 | 2121 |

MySQL Connector C++

2122 | 2123 | Home:[http://dev.mysql.com/doc/connector-cpp/en/] 2124 | 2125 | 这是 MySQL 官方提供的 C++ 封装。 2126 | 2127 | 代码示例——执行 SQL 语句 2128 | 2129 | sql::mysql::MySQL_Driver* driver = sql::mysql::MySQL_Driver::get_mysql_driver_instance(); 2130 | sql::Connection* conn = driver->connect("tcp://127.0.0.1:3306", "user", "password"); 2131 | sql::Statement* stmt = conn->createStatement(); 2132 | 2133 | stmt->execute("USE EXAMPLE_DB"); 2134 | stmt->execute("DROP TABLE IF EXISTS test"); 2135 | stmt->execute("CREATE TABLE test(id INT, label CHAR(1))"); 2136 | stmt->execute("INSERT INTO test(id, label) VALUES (1, 'a')"); 2137 | 2138 | delete stmt; 2139 | stmt = NULL; 2140 | delete conn; 2141 | conn = NULL; 2142 | 2143 | 2144 |

MySQL++

2145 | 2146 | Home:[http://www.tangentsoft.net/mysql%2B%2B/] 2147 | 2148 | 这是个老牌的库,诞生于1998年,提供了 MySQL API 的 C++ 封装。 2149 | 2150 | 代码示例——执行 SQL 语句 2151 | 2152 | #include 2153 | #include 2154 | 2155 | void query(db_name, server_name, user, password) 2156 | { 2157 | using namespace std; 2158 | 2159 | mysqlpp::Connection conn(false); 2160 | if(!conn.connect(db_name, server_name, user, password)) 2161 | { 2162 | cerr << "DB connection failed: " << conn.error() << endl; 2163 | return; 2164 | } 2165 | 2166 | mysqlpp::Query query = conn.query("select item from table1"); 2167 | mysqlpp::StoreQueryResult sqr = query.store() 2168 | if(!sqr) 2169 | { 2170 | cerr << "Failed to get item list: " << query.error() << endl; 2171 | return; 2172 | } 2173 | 2174 | mysqlpp::StoreQueryResult::const_iterator iter; 2175 | for(iter=sqr.begin(); iter!=sqr.end(); ++iter) 2176 | { 2177 | mysqlpp::Row row = *iter; 2178 | cout << '\t' << row[0] << endl; 2179 | } 2180 | } 2181 | 2182 | 2183 |

POCO::Data::MySQL

2184 | 2185 | Docs:[http://pocoproject.org/docs/package-MySQL.MySQL.html] 2186 | 2187 | POCO 前面已经介绍过。它提供了 MySQL 的封装类 2188 | 2189 | === 9.2.3 PostgreSQL 封装库 === 2190 | 2191 |

libpq

2192 | 2193 | Home:[http://www.postgresql.org/docs/9.4/static/libpq.html] 2194 | 2195 | 这是由 PostgreSQL 官方提供的 C 封装类库。 2196 | 2197 |

libpqxx

2198 | 2199 | Home:[http://pqxx.org/development/libpqxx/] 2200 | 2201 | 这是由 PostgreSQL 官方提供的 C++ 封装类库。 2202 | 2203 | 代码示例 2204 | 2205 | #include 2206 | #include 2207 | 2208 | void update(const std::string& name) 2209 | { 2210 | pqxx::connection conn("dbname=company user=accounting"); 2211 | pqxx::work txn(conn); 2212 | 2213 | pqxx::result r = txn.exec("SELECT id FROM Employee WHERE name =" + name); 2214 | if(r.size() != 1) 2215 | { 2216 | std::cerr << "Expected 1 employee with name " << name << ", " 2217 | << "but found " << r.size() << std::endl; 2218 | return 1; 2219 | } 2220 | 2221 | int employee_id = r[0][0].as(); 2222 | std::cout << "Updating employee #" << employee_id << std::endl; 2223 | 2224 | txn.exec( 2225 | "UPDATE EMPLOYEE SET salary = salary + 1 " 2226 | "WHERE id = " + txn.quote(employee_id) 2227 | ); 2228 | 2229 | txn.commit(); 2230 | } 2231 | 2232 | 2233 | === 9.2.4 Oracle 封装库 === 2234 | 2235 |

OCILIB

2236 | 2237 | Home:[http://vrogier.github.io/ocilib/] 2238 | 2239 | 这是一个跨平台的 C 开源库。如其名,它封装了 Oracle 官方的 OCI(Oracle Call Interface)。 2240 | 2241 | 它同时还提供了 C++ 的 API。 2242 | 2243 | 代码示例 2244 | 2245 | #include 2246 | using namespace ocilib; 2247 | 2248 | int main() 2249 | { 2250 | try 2251 | { 2252 | Environment::Initialize(); 2253 | Connection conn("db", "user", "password"); 2254 | Statement stmt(conn); 2255 | stmt.Execute("select intcol, strcol from table"); 2256 | 2257 | Resultset rs = stmt.GetResultset(); 2258 | while(rs.Next()) 2259 | { 2260 | std::cout << rs.Get(1) << " - " << rs.Get(2) << std::endl; 2261 | } 2262 | } 2263 | catch(std::exception& err) 2264 | { 2265 | std::cout << err.what() << std::endl; 2266 | } 2267 | 2268 | Environment::Cleanup(); 2269 | return 0; 2270 | } 2271 | 2272 | 2273 | === 9.2.5 DB2 封装库 === 2274 | 2275 | === 9.2.6 SQLite 封装库 === 2276 | 2277 |

官方的 C API

2278 | 2279 | Docs:[http://sqlite.org/c3ref/intro.html] 2280 | 2281 | SQLite 前面已经介绍过。由于 SQLite 本身就是用 C 语言开发的,因此它直接提供了基于 C 的 API 接口。 2282 | 2283 | 代码示例 2284 | 2285 | #include 2286 | #include 2287 | 2288 | static int callback(void* NotUsed, int argc, char** argv, char** azColName) 2289 | { 2290 | for(int i=0; i 2327 | 2328 |

POCO::Data::SQLite

2329 | 2330 | Docs:[http://pocoproject.org/docs/package-SQLite.SQLite.html] 2331 | 2332 | POCO 前面已经介绍过。它提供了 sqlite 的封装类 2333 | 2334 | === 9.2.7 Redis 封装库 === 2335 | 2336 |

Hiredis

2337 | 2338 | Home:[https://github.com/redis/hiredis] 2339 | 2340 | 这是 Redis 官方提供的 C 客户端,很轻量级,支持“异步 API”。 2341 | 2342 | 代码示例——结合 libev 进行异步调用 2343 | 2344 | #include 2345 | #include 2346 | #include 2347 | #include 2348 | 2349 | #include 2350 | #include 2351 | #include 2352 | 2353 | void getCallback(redisAsyncContext* context, void* r, void* privdata) 2354 | { 2355 | redisReply* reply = r; 2356 | if(reply == NULL) 2357 | { 2358 | return; 2359 | } 2360 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 2361 | redisAsyncDisconnect(context); /* Disconnect after receiv reply */ 2362 | } 2363 | 2364 | void connectCallback(const redisAsyncContext* context, int status) 2365 | { 2366 | if(status != REDIS_OK) 2367 | { 2368 | printf("Error: %s\n", context->errstr); 2369 | return; 2370 | } 2371 | printf("Connected...\n"); 2372 | } 2373 | 2374 | void disconnectCallback(const redisAsyncContext* context, int status) 2375 | { 2376 | if(status != REDIS_OK) 2377 | { 2378 | printf("Error: %s\n", context->errstr); 2379 | return; 2380 | } 2381 | printf("Disconnected...\n"); 2382 | } 2383 | 2384 | int main(int argc, char* argv[]) 2385 | { 2386 | signal(SIGPIPE, SIG_IGN); 2387 | 2388 | redisAsyncContext* context = redisAsyncConnect("127.0.0.1", 6379); 2389 | if(context->err) 2390 | { 2391 | printf("Error: %s\n", context->errstr); 2392 | return 1; /* Let *context leak for now... */ 2393 | } 2394 | 2395 | redisLibevAttach(EV_DEFAULT_ context); 2396 | redisAsyncSetConnectCallback(context, connectCallback); 2397 | redisAsyncSetDisconnectCallback(context, disconnectCallback); 2398 | redisAsyncCommand(context, NULL, NULL, 2399 | "SET key %b", argv[argc-1], strlen(argv[argc-1])); 2400 | redisAsyncCommand(context, getCallback, (char*)"end-1", "GET key"); 2401 | ev_loop(EV_DEFAULT_ 0); 2402 | return 0; 2403 | } 2404 | 2405 | 2406 | === 9.2.8 MongoDB 封装库 === 2407 | 2408 |

官方的 C API

2409 | 2410 | Docs:[https://api.mongodb.org/c/current/] 2411 | 2412 | MongoDB 前面已经介绍过。这是其官方提供的 API。 2413 | 2414 | 代码示例 2415 | 2416 | #include 2417 | #include 2418 | #include 2419 | 2420 | int main() 2421 | { 2422 | mongoc_init(); 2423 | 2424 | mongoc_client_t* client = mongoc_client_new("mongodb://localhost:27017/"); 2425 | mongoc_collection_t* collection = mongoc_client_get_collection(client, "test", "test"); 2426 | 2427 | bson_t* doc = bson_new(); 2428 | 2429 | bson_oid_t oid; 2430 | bson_oid_init(&oid, NULL); 2431 | BSON_APPEND_OID(doc, "_id", &oid); 2432 | BSON_APPEND_UTF8(doc, "hello", "world"); 2433 | 2434 | bson_error_t error; 2435 | if(!mongoc_collection_insert(collection, MONGOC_INSERT_NONE, doc, NULL, &error)) 2436 | { 2437 | printf("%s\n", error.message); 2438 | } 2439 | 2440 | bson_destroy(doc); 2441 | mongoc_collection_destroy(collection); 2442 | mongoc_client_destroy(client); 2443 | 2444 | return 0; 2445 | } 2446 | 2447 | 2448 |

POCO::MongoDB

2449 | 2450 | Docs:[http://pocoproject.org/docs/package-MongoDB.MongoDB.html] 2451 | 2452 | POCO 前面已经介绍过。它提供了 MongoDB 的封装类 2453 | 2454 | == 9.3 ODBC 相关 == 2455 | 2456 |

unixODBC

2457 | 2458 | Home:[http://www.unixodbc.org/] 2459 | 2460 | Links:[https://en.wikipedia.org/wiki/UnixODBC Wikipedia] 2461 | 2462 | 诞生于1999年,实现了全套的 ODBC 架构,包括:驱动管理器、相关的 GUI 界面和命令行界面。支持多种操作系统。 2463 | 2464 |

Libodbc++

2465 | 2466 | Home:[http://libodbcxx.sourceforge.net/] 2467 | 2468 | 如其名,这是专门封装 ODBC 的 C++ 类库,支持多种操作系统。它提供的 API 类似于 JDBC 的 API 2469 | 2470 |

POCO::Data::ODBC

2471 | 2472 | Docs:[http://pocoproject.org/docs/package-ODBC.ODBC.html] 2473 | 2474 | POCO 前面已经介绍过。它提供了操作 ODBC 的封装类。 2475 | 2476 | == 9.4 ORM(Object-Relational Mapping) == 2477 | 2478 |

ODB

2479 | 2480 | Home:[http://www.codesynthesis.com/products/odb] 2481 | 2482 | Links:[https://en.wikipedia.org/wiki/ODB_%28C%2B%2B%29 Wikipedia] 2483 | 2484 | 它的特色是:可以根据 C++ 类定义自动生成数据库的表结构。 2485 | 2486 | 为了获得高性能,它直接调用具体数据库的原生 API。支持的数据库包括:MySQL、PostgreSQL、Oracle、SQL Server、SQLite 2487 | 2488 | 代码示例——声明一个可持久化的类 2489 | 2490 | // 通过预处理语句“#pragma”来进行某些定制 2491 | 2492 | #pragma db object table("people") 2493 | class person 2494 | { 2495 | public: 2496 | // ...... 2497 | 2498 | private: 2499 | friend class odb::access; 2500 | person(); 2501 | 2502 | #pragma db id auto 2503 | unsigned long id_; 2504 | 2505 | string first_; 2506 | string last_; 2507 | 2508 | #pragma type("INT UNSIGNED") 2509 | unsigned short age_; 2510 | }; 2511 | 2512 | 2513 | 代码示例——查询 2514 | 2515 | typedef odb::query query; 2516 | typedef odb::result result; 2517 | 2518 | transaction trans(db.begin()); 2519 | result r(db.query(query::last == "Doe" && query::age < 30)); 2520 | 2521 | for(result::iterator i(r.begin()); i!=r.end(); ++i) 2522 | { 2523 | cout << "Hello, " << i->first() << endl; 2524 | } 2525 | 2526 | trans.commit(); 2527 | 2528 | 2529 |

hiberlite

2530 | 2531 | Home:[https://github.com/paulftw/hiberlite] 2532 | 2533 | 专门提供给 Sqlite 的 ORM 封装库。基于 C++ 开发,其 API 采用类似 Boost.Serialization 的风格。 2534 | 2535 | ---- 2536 | 2537 | = 10 Web = 2538 | 2539 | == 10.1 HTTP Server == 2540 | 2541 |

Apache HTTP Server

2542 | 2543 | Home:[https://httpd.apache.org/] 2544 | 2545 | Links:[https://en.wikipedia.org/wiki/Apache_HTTP_Server Wikipedia] [https://zh.wikipedia.org/wiki/Apache_HTTP_Server 维基百科] 2546 | 2547 | 大名鼎鼎的 Apache,诞生于1995年,采用 C 和 C++ 开发。长期作为 Web Server 市场份额的老大。 2548 | 2549 |

Nginx

2550 | 2551 | Home:[http://nginx.org/] 2552 | 2553 | Links:[https://en.wikipedia.org/wiki/Nginx Wikipedia] [https://zh.wikipedia.org/wiki/Nginx 维基百科] 2554 | 2555 | Web Server 的后起之秀,诞生于2002年,采用 C 语言开发。其市场份额如今排名第二。 2556 | 2557 |

POCO::Net

2558 | 2559 | Docs:[http://pocoproject.org/docs/package-Net.HTTPServer.html] 2560 | 2561 | POCO 前面已经介绍过。它提供了 HTTP Server 的封装类 2562 | 2563 |

Dlib::server_http

2564 | 2565 | Docs:[http://dlib.net/network.html#server_http] 2566 | 2567 | Dlib 前面已经介绍过。它提供了一个简单的 HTTP Server 的类(server_http)。 2568 | 2569 | == 10.2 HTTP Client == 2570 | 2571 |

cURL & libcurl

2572 | 2573 | Docs:[http://curl.haxx.se/libcurl/c/] 2574 | 2575 | libcurl 前面已经介绍过。它提供了【完整的】HTTP 协议支持。另,HTTP 2.0 标准刚出来不久,它就已经支持了。 2576 | 2577 | 代码示例——HTTP POST 2578 | 2579 | #include 2580 | #include 2581 | 2582 | int main() 2583 | { 2584 | curl_global_init(CURL_GLOBAL_ALL); 2585 | 2586 | CURL* curl = curl_easy_init(); 2587 | if(curl) 2588 | { 2589 | curl_easy_setopt(curl, CURLOPT_URL, "http://post.example.com/foo.cgi"); 2590 | curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl"); 2591 | 2592 | CURLcode res = curl_easy_perform(curl); 2593 | if(res != CURLE_OK) // Check for errors 2594 | { 2595 | fprintf(stderr, "curl_easy_perform() failed: %s\n", 2596 | curl_easy_strerror(res)); 2597 | } 2598 | curl_easy_cleanup(curl); // always cleanup 2599 | } 2600 | 2601 | curl_global_cleanup(); 2602 | return 0; 2603 | } 2604 | 2605 | 2606 |

POCO::Net

2607 | 2608 | Docs:[http://pocoproject.org/docs/package-Net.HTTPClient.html] 2609 | 2610 | POCO 前面已经介绍过。它提供了 HTTP Client 的封装类。 2611 | 2612 |

cpr

2613 | 2614 | Home:[https://github.com/whoshuu/cpr] 2615 | 2616 | 类似 Python 的 [http://docs.python-requests.org/ Requests 库],以【优雅的语法】实现 HTTP 请求。 2617 | 2618 | 代码示例——HTTP GET 2619 | 2620 | #include 2621 | 2622 | int main() 2623 | { 2624 | auto r = cpr::Get(cpr::Url{"https://api.github.com/repos/whoshuu/cpr/contributors"}, 2625 | cpr::Authentication{"user", "pass"}, 2626 | cpr::Parameters{{"anon", "true"}, {"key", "value"}}); 2627 | r.status_code; // 200 2628 | r.header["content-type"]; // application/json; charset=utf-8 2629 | r.text; // JSON text string 2630 | return 0; 2631 | } 2632 | 2633 | 2634 | == 10.3 浏览器引擎 == 2635 | 2636 |

WebKit

2637 | 2638 | Home:[https://www.webkit.org/] 2639 | 2640 | Links:[https://en.wikipedia.org/wiki/WebKit Wikipedia] [https://zh.wikipedia.org/wiki/WebKit 维基百科] 2641 | 2642 | 它是很多浏览器使用的渲染引擎,基于 C++ 开发。 2643 | 2644 |

Gecko

2645 | 2646 | Home:[https://developer.mozilla.org/] 2647 | 2648 | Links:[https://en.wikipedia.org/wiki/Gecko_(software) Wikipedia] [https://zh.wikipedia.org/wiki/Gecko 维基百科] 2649 | 2650 | 它是 Firefox 的渲染引擎,基于 C++ 开发,由 Mozilla 社区维护。 2651 | 2652 | == 10.4 浏览器整合 == 2653 | 2654 |

CEF(Chromium Embedded Framework)

2655 | 2656 | Home:[https://bitbucket.org/chromiumembedded/cef] 2657 | 2658 | Links:[https://en.wikipedia.org/wiki/Chromium_Embedded_Framework Wikipedia] 2659 | 2660 | 如其名,它提供了嵌入 Chrome 浏览器的框架。采用 C++ 开发。好几个商业公司(Google、Adobe、Facebook、Evernote...)的产品用到它。 2661 | 2662 | 以下是其它开源项目针对 CEF 的扩展,提供了其它编程语言的绑定。 2663 | 2664 | * dotNet - [https://github.com/chillitom/CefSharp] 2665 | 2666 | * dotNet (CEF1) - [https://bitbucket.org/fddima/cefglue] 2667 | 2668 | * dotNet/Mono (CEF3) - [https://bitbucket.org/xilium/xilium.cefglue] 2669 | 2670 | * dotNet (CEF3) - [https://bitbucket.org/chromiumfx/chromiumfx] 2671 | 2672 | * Java - [https://bitbucket.org/chromiumembedded/java-cef] 2673 | 2674 | * Go - [https://github.com/CzarekTomczak/cef2go] 2675 | 2676 | * Delphi (CEF3) - [https://github.com/hgourvest/dcef3] 2677 | 2678 |

PhantomJS

2679 | 2680 | Home:[http://phantomjs.org/] 2681 | 2682 | Links:[https://en.wikipedia.org/wiki/PhantomJS Wikipedia] 2683 | 2684 | 2011年才诞生的。基于 C++ 开发,整合了 WebKit。 2685 | 2686 | 它本身没有提供 GUI 界面。但是提供了 JavaScript 的 API,让你可以操纵 WebKit 引擎。可以利用它进行 Web 界面的单元测试。 2687 | 2688 | == 10.5 (其它) == 2689 | 2690 |

WebSocket++

2691 | 2692 | Home:[http://www.zaphoyd.com/websocketpp/] 2693 | 2694 | 顾名思义,它提供了 [https://en.wikipedia.org/wiki/WebSocket WebSocket] 的 C++ 封装,基于 Boost Asio 构建。 2695 | 2696 | 支持多种操作系统平台,支持 TLS、proxy、IPv6。 2697 | 2698 | ---- 2699 | 2700 | = 11 信息安全 = 2701 | 2702 | == 11.1 密码学 == 2703 | 2704 |

Crypto++

2705 | 2706 | Docs:[http://www.cryptopp.com/docs/ref/annotated.html] 2707 | 2708 | Crypto++ 前面已经介绍过。它提供了常见的对称加密算法(DES、AES、IDEA 等)、公钥加密算法(RSA、DSA 等)、散列算法(MD5、SHA1、RIPEMD 等)。 2709 | 2710 | 代码示例——计算 SHA256 散列值 2711 | 2712 | #include 2713 | using namespace CryptoPP; 2714 | 2715 | const byte* pbData = ...; // 要计算的数据的地址 2716 | unsigned int nDataLen = ...; // 字节数 2717 | byte abDigest[SHA256::DIGESTSIZE]; 2718 | SHA256().CalculateDigest(abDigest, pbData, nDataLen); 2719 | // 注:abDigest 中通常会包含不可见字符,要输出为可见字符串需要做一下 Hex 编码 2720 | 2721 | 2722 |

OpenSSL

2723 | 2724 | Home:[https://www.openssl.org/] 2725 | 2726 | Links:[https://en.wikipedia.org/wiki/OpenSSL Wikipedia] [https://zh.wikipedia.org/wiki/OpenSSL 维基百科] 2727 | 2728 | OpenSSL 基于 C 语言开发,在加密领域那可是大名鼎鼎。大部分常用的加密算法(对称、非对称)和散列算法,它都支持。 2729 | 2730 | 很多知名的软件(包括 Web Server)用到它,所以2014年的“[https://zh.wikipedia.org/wiki/%E5%BF%83%E8%84%8F%E5%87%BA%E8%A1%80%E6%BC%8F%E6%B4%9E 心脏滴血漏洞]”让好多网站中招。 2731 | 2732 |

LibreSSL

2733 | 2734 | Home:[http://www.libressl.org/] 2735 | 2736 | Links:[https://en.wikipedia.org/wiki/LibreSSL Wikipedia] [https://zh.wikipedia.org/wiki/LibreSSL 维基百科] 2737 | 2738 | OpenSSL 爆出“心脏滴血漏洞”之后,OpenBSD 社区的程序员复制了 OpenSSL 版本 1.0.1g 的代码,然后另起炉灶。 2739 | 2740 | LibreSSL 的主要目标是“安全性”,其维护人员删除了原 OpenSSL 中大量过时的代码,替换了相关的内存管理函数(规避缓冲区溢出),增强了随机数生成算法.... 2741 | 2742 |

GnuTLS

2743 | 2744 | Home:[http://gnutls.org/] 2745 | 2746 | Links:[https://en.wikipedia.org/wiki/GnuTLS Wikipedia] 2747 | 2748 | 采用 C 语言开发,名气也挺大。如其名,主要提供 TLS/SSL 的相关功能。 2749 | 2750 |

NaCl

2751 | 2752 | Home:[http://nacl.cr.yp.to/] 2753 | 2754 | Links:[https://en.wikipedia.org/wiki/NaCl_%28software%29 Wikipedia] 2755 | 2756 | 这个名称是“Networking and Cryptography library”的缩写。 2757 | 2758 | 它采用 C 语言开发,另有其它编程语言(Python、Ruby、PHP)的 API 绑定。 2759 | 2760 | 它的作者同时也是 [https://en.wikipedia.org/wiki/Qmail qmail] 和 [https://en.wikipedia.org/wiki/Curve25519 Curve25519] 的作者。 2761 | 2762 |

libsodium

2763 | 2764 | Home:[https://github.com/jedisct1/libsodium] 2765 | 2766 | 它派生自 NaCl,提供了跟 NaCl 兼容的 API。支持的操作系统平台更多。 2767 | 2768 | shadowsocks 和 dnscrypt-proxy 用到它。 2769 | 2770 |

Keyczar

2771 | 2772 | Home:[https://github.com/google/keyczar] 2773 | 2774 | 这是 Google 提供的加密库,同时提供 C++、Java、Python 三种语言的实现。 2775 | 2776 | 它提供了比较高层的 API, 使用者无需关心太多的细节。 2777 | 2778 | 代码示例——加密/解密文本 2779 | 2780 | #include 2781 | #include 2782 | #include 2783 | #include 2784 | 2785 | void test(const std::string& key_location) 2786 | { 2787 | keyczar::Keyczar* crypter = keyczar::Crypter::Read(key_location); 2788 | if(!crypter) 2789 | { 2790 | return; 2791 | } 2792 | 2793 | std::string plain = "Secret message"; 2794 | std::cout << "Plain text: " << plain << std::endl; 2795 | 2796 | std::string cipher; 2797 | if(crypter->Encrypt(plain, &cipher)) 2798 | { 2799 | std::cout << "Cipher text (Base64w): " << cipher << std::endl; 2800 | std::string decrypted; 2801 | if(crypter->Decrypt(cipher, &decrypted)) 2802 | { 2803 | assert(plain == decrypted); 2804 | } 2805 | } 2806 | delete crypter; 2807 | } 2808 | 2809 | 2810 |

POCO::Crypto

2811 | 2812 | Docs:[http://pocoproject.org/docs/Poco.Crypto.html] 2813 | 2814 | POCO 前面已经介绍过。它提供了常见的加密算法和哈希算法。 2815 | 2816 | ---- 2817 | 2818 | = 12 处理文件格式 = 2819 | 2820 | == 12.1 结构化数据格式 == 2821 | 2822 | === 12.1.1 CSV === 2823 | 2824 | [https://en.wikipedia.org/wiki/Comma-separated_values CSV] 是一种历史悠久的结构化数据存储格式。其效果类似于一张数据库二维表。 2825 | 2826 |

Boost.Tokenizer

2827 | 2828 | Docs:[http://boost.org/libs/tokenizer] 2829 | 2830 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,用来灵活地切割字符串。使用它,可以帮你提取 CSV 的行和列。 2831 | 2832 | === 12.1.2 JSON === 2833 | 2834 | JSON 格式源自 JavaScript,如今在 Web 开发中广为应用。 2835 | 2836 |

Boost.PropertyTree

2837 | 2838 | Docs:[http://boost.org/libs/property_tree] 2839 | 2840 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,封装了某种特殊的“树”结构(property_tree)。它支持对 JSON 的读写。 2841 | 2842 | 代码示例——读写 JSON 字符串 2843 | 2844 | #include 2845 | #include 2846 | #include 2847 | 2848 | using boost::property_tree::ptree; 2849 | using boost::property_tree::read_json; 2850 | using boost::property_tree::write_json; 2851 | 2852 | // Write json 2853 | ptree pt1; 2854 | pt1.put("foo", "bar"); 2855 | std::ostringstream oss; 2856 | write_json(oss, pt1, false); 2857 | std::string json = oss.str(); // {"foo":"bar"} 2858 | 2859 | // Read json 2860 | std::istringstream iss(json); 2861 | ptree pt2; 2862 | read_json(iss, pt2); 2863 | std::string value = pt2.get("foo"); 2864 | 2865 | 2866 |

POCO::JSON

2867 | 2868 | Docs:[http://pocoproject.org/docs/package-JSON.JSON.html] 2869 | 2870 | POCO 前面已经介绍过。它提供了 JSON 的封装类 2871 | 2872 |

rapidjson

2873 | 2874 | Home:[https://github.com/miloyip/rapidjson] 2875 | 2876 | 这是一个 C++ 的 JSON 库。提供了 SAX 和 DOM 风格的 API。 2877 | 2878 | (另,作者是香港同胞) 2879 | 2880 |

jsoncpp

2881 | 2882 | Home:[https://github.com/open-source-parsers/jsoncpp] 2883 | 2884 | 如其名,这是个 C++ 的 JSON 封装库。 2885 | 2886 | === 12.1.3 YAML === 2887 | 2888 | [https://en.wikipedia.org/wiki/YAML YAML] 是一种类似于 json 的结构化数据格式。它在确保可读性的基础上,提供了超越 json 的灵活性和扩展性。 2889 | 2890 |

yaml-cpp

2891 | 2892 | Home:[https://github.com/jbeder/yaml-cpp] 2893 | 2894 | C++ 实现的 YAML 解析器。 2895 | 2896 |

LibYAML

2897 | 2898 | Home:[http://pyyaml.org/wiki/LibYAML] 2899 | 2900 | C 语言实现的 YAML 解析器。 2901 | 2902 | == 12.2 压缩文件 & 打包文件 == 2903 | 2904 | === 12.2.1 综合性的库 === 2905 | 2906 |

libarchive

2907 | 2908 | Home:[http://www.libarchive.org/] 2909 | 2910 | C 语言实现,支持的格式: 2911 | 2912 | 可读写的格式:zip、gzip、bzip2、xz、lzma、tar、ISO、cpio、ar、pax、mtree; 2913 | 2914 | 只读的格式:7z、rar、cab、rpm、lzh、lzop、raw、xar 2915 | 2916 |

LZMA SDK

2917 | 2918 | Home:[http://www.7-zip.org/sdk.html] 2919 | 2920 | 这是由 7-zip 官方提供的。7-zip 就是用它进行压缩/解压缩。 2921 | 2922 | 支持的格式:7z、LZMA、LZMA2、XZ 2923 | 2924 |

PhysicsFS

2925 | 2926 | Home:[http://icculus.org/physfs/] 2927 | 2928 | Links:[https://en.wikipedia.org/wiki/PhysicsFS Wikipedia] 2929 | 2930 | 针对不同的压缩/归档格式,提供了类似 VFS 的抽象封装层。主要用于游戏开发中。 2931 | 2932 | 支持的格式:zip、7z、GRP、PAK、HOG、MVL、WAD... 2933 | 2934 |

zopfli

2935 | 2936 | Home:[https://github.com/google/zopfli] 2937 | 2938 | 这是由 Google 开发的 C 库,提供对 zip 和 gzip 格式的压缩(不提供解压)。 2939 | 2940 | 压缩的速度比较慢,但是可以得到更高的压缩率。 2941 | 2942 | === 12.2.2 zip === 2943 | 2944 | [https://en.wikipedia.org/wiki/Zip_%28file_format%29 格式说明] 2945 | 2946 |

libzip

2947 | 2948 | Home:[http://www.nih.at/libzip/] 2949 | 2950 | Links:[https://en.wikipedia.org/wiki/Libzip Wikipedia] 2951 | 2952 | 用 C 语言开发的库,基于 zlib 库。 2953 | 2954 |

Poco::Zip

2955 | 2956 | Docs:[http://pocoproject.org/docs/Poco.Zip.html] 2957 | 2958 | POCO 前面已经介绍过。它提供了若干封装类,用于 zip 格式的压缩和解压。 2959 | 2960 | === 12.2.3 bzip2(bz2) === 2961 | 2962 | [https://en.wikipedia.org/wiki/Bzip2 格式说明] 2963 | 2964 |

libbzip2

2965 | 2966 | Home:[http://bzip.org/] 2967 | 2968 | 这是 bzip2 官方提供的库,C 语言实现。 2969 | 2970 | === 12.2.4 gzip(gz) === 2971 | 2972 |

zlib

2973 | 2974 | Home:[http://zlib.net/] 2975 | 2976 | Links:[https://en.wikipedia.org/wiki/Zlib Wikipedia] [https://zh.wikipedia.org/wiki/Zlib 维基百科] 2977 | 2978 | C 语言实现,诞生于1995年,被大量的开源项目使用(OpenSSL、OpenSSH、Apache、PostgreSQL、Git、libpng......)。 2979 | 2980 | === 12.2.5 tar === 2981 | 2982 |

libtar

2983 | 2984 | Home:[http://www.feep.net/libtar/] 2985 | 2986 | 基于 C 语言开发,可以对 tar 格式添加内容或读取内容。 2987 | 2988 | === 12.2.6 rar === 2989 | 2990 |

unrarlib

2991 | 2992 | Home:[http://www.unrarlib.org/] 2993 | 2994 | 该项目的开发已经停止。只支持对 RAR2 格式的解压缩。 2995 | 2996 | === 12.2.7 snappy === 2997 | 2998 |

snappy

2999 | 3000 | Home:[https://google.github.io/snappy/] 3001 | 3002 | 由 Google 开发的压缩格式,特点是非常快(不论是压缩还是解压);但是压缩率不如 gzip。 3003 | 3004 | 起先被用于 Google 内部的 BigTable,如今被用于多种 NoSQL 数据库(比如:Cassandra、Hadoop、LevelDB、MongoDB、RocksDB...) 3005 | 3006 | 支持多种语言的绑定(C#、Common Lisp、Erlang、Go、Haskell、Lua、Java、Node.js、Perl、PHP、Python、R、Ruby、Smalltalk) 3007 | 3008 | === 12.2.8 Brotli === 3009 | 3010 |

Brotli

3011 | 3012 | Home:[https://github.com/google/brotli] 3013 | 3014 | Links:[https://en.wikipedia.org/wiki/Brotli Wikipedia] 3015 | 3016 | 由 Google 开发的压缩格式,压缩率很高(据说高于 LZMA 和 bz2)。 3017 | 3018 | 该算法很新,是2015年9月才发布的。 3019 | 3020 | === 12.2.9 LZFSE === 3021 | 3022 |

LZFSE

3023 | 3024 | Home:[https://github.com/lzfse/lzfse] 3025 | 3026 | Links:[https://zh.wikipedia.org/wiki/LZFSE 维基百科] 3027 | 3028 | 由苹果开发的压缩格式。苹果称它的压缩率与“ZLib level 5”相似,但速度快2至3倍。 3029 | 3030 | 该算法是前不久(2016年7月)才开源出来的。 3031 | 3032 | == 12.3 标记语言 == 3033 | 3034 | === 12.3.1 XML === 3035 | 3036 |

Expat

3037 | 3038 | Home:[http://www.libexpat.org/] 3039 | 3040 | Links:[https://en.wikipedia.org/wiki/Expat_(library) Wikipedia] 3041 | 3042 | 基于 C 语言实现,诞生于1998年。很多知名的开源项目(Apache Server、Firefox、Python、PHP、Perl)用到它。 3043 | 3044 |

libxml2

3045 | 3046 | Home:[http://xmlsoft.org/] 3047 | 3048 | Links:[https://en.wikipedia.org/wiki/Libxml2 Wikipedia] 3049 | 3050 | 基于 C 语言实现,诞生于1999年。提供了多种语言(C++、Python、Ruby、Common Lisp、PHP、Perl)的 API 绑定。 3051 | 3052 |

wxWidgets

3053 | 3054 | Docs:[http://docs.wxwidgets.org/trunk/group__group__class__xml.html] 3055 | 3056 | wxWidgets 前面已经介绍过。它提供了 XML 的封装类,其内部是基于 Expat 进行解析。 3057 | 3058 |

POCO::XML

3059 | 3060 | Docs:[http://pocoproject.org/docs/package-XML.XML.html] 3061 | 3062 | POCO 前面已经介绍过。它提供了 XML 的封装类。 3063 | 3064 |

libxml++

3065 | 3066 | Home:[http://libxmlplusplus.sourceforge.net/] 3067 | 3068 | 如其名,它是针对前面提到的 libxml2 的 C++ 封装。 3069 | 3070 | === 12.3.2 HTML === 3071 | 3072 |

htmlcxx

3073 | 3074 | Home:[http://htmlcxx.sourceforge.net/] 3075 | 3076 | 如其名,是基于 C++ 开发的。支持 HTML 和 CSS 的解析。 3077 | 3078 | == 12.4 PDF == 3079 | 3080 |

PoDoFo

3081 | 3082 | Home:[http://podofo.sourceforge.net/] 3083 | 3084 | 基于 C++ 开发的跨平台库,名称取自“Portable Document Format”每个单词的头两个字母 :) 3085 | 3086 | 它既支持 PDF 文件的生成,也支持 PDF 内容的提取。它同时还提供[http://podofo.sourceforge.net/tools.html 一堆命令行的小工具],用来操作 PDF 文件。 3087 | 3088 |

Poppler

3089 | 3090 | Home:[https://poppler.freedesktop.org/] 3091 | 3092 | Links:[https://en.wikipedia.org/wiki/Poppler_%28software%29 Wikipedia] 3093 | 3094 | 派生自 Xpdf 3.0 的开源库,用于渲染 PDF 的内容。很多开源的 PDF 阅读软件用到它。 3095 | 3096 | 在开源界,它第一个【完整】实现了 ISO 32000-1(PDF 的 ISO 标准)。 3097 | 3098 | 它内置了若干命令行工具(poppler-utils),可以用来进行 PDF 的内容提取和格式转换。 3099 | 3100 |

LibHaru

3101 | 3102 | Home:[http://libharu.org/] 3103 | 3104 | Links:[https://en.wikipedia.org/wiki/LibHaru Wikipedia] 3105 | 3106 | 它是基于 C 语言开发的跨平台库,可以用来生成 PDF 文件格式。 3107 | 3108 | 代码示例 3109 | 3110 | #include 3111 | 3112 | // 创建文档对象 3113 | HPDF_Doc doc = HPDF_New(error_handler, NULL); 3114 | if(!doc) 3115 | { 3116 | printf("ERROR: cannot create pdf object.\n"); 3117 | return 1; 3118 | } 3119 | 3120 | // 设置文档属性 3121 | HPDF_SetCompressionMode(doc, HPDF_COMP_ALL); 3122 | HPDF_SetPageMode(doc, HPDF_PAGE_MODE_USE_OUTLINE); 3123 | HPDF_SetPassword(doc, "owner pwd", "user pwd"); 3124 | 3125 | // 添加一页 3126 | HPDF_Page page_1 = HPDF_AddPage(doc); 3127 | // 设置页属性 3128 | HPDF_Page_SetSize(page_1, HPDF_PAGE_SIZE_B5, HPDF_PAGE_LANDSCAPE); 3129 | 3130 | // 保存到文件 3131 | HPDF_SaveToFile(doc, "test.pdf"); 3132 | 3133 | // 结束 3134 | HPDF_Free(doc); 3135 | 3136 | 3137 | == 12.5 MS Office 文档 == 3138 | 3139 |

wvWare

3140 | 3141 | Home:[http://wvware.sourceforge.net/] 3142 | 3143 | 它能够读取 Word 文档的内容,支持的 Word 版本是(2000、97、95、6)。 3144 | 3145 | AbiWord 和 KWord 用到它。 3146 | 3147 | == 12.6 RTF == 3148 | 3149 |

LibRTF

3150 | 3151 | Home:[http://sourceforge.net/projects/librtf/] 3152 | 3153 | C 语言实现的库,可以解析 RTF 文件格式。 3154 | 3155 | == 12.7 CHM == 3156 | 3157 |

CHMLIB

3158 | 3159 | Home:[http://www.jedrea.com/chmlib/] 3160 | 3161 | 这是一个轻量级的库,基于 C 语言开发,可以用来提取 CHM 格式文件的内容。 3162 | 3163 | 它提供了多种编程语言(C++、Python、Perl、Common Lisp)的 API 绑定。 3164 | 3165 |

libCHMxx

3166 | 3167 | Home:[http://www.mare.ee/indrek/libchmxx/] 3168 | 3169 | 它就是基于 CHMLIB 的 C++ 封装库。 3170 | 3171 | ---- 3172 | 3173 | = 13 图像 = 3174 | 3175 | == 13.1 图像处理 == 3176 | 3177 |

ImageMagick

3178 | 3179 | Home:[http://imagemagick.org/] 3180 | 3181 | Links:[https://en.wikipedia.org/wiki/ImageMagick Wikipedia] [https://zh.wikipedia.org/wiki/ImageMagick 维基百科] 3182 | 3183 | ImageMagick 可说是最强大的开源图片处理工具集,采用 C 语言编写。诞生于1990年,其开发至今依然非常活跃。支持非常多的操作系统平台。 3184 | 3185 | 它提供许多编程语言的 API,对于 C++ 是 [http://www.imagemagick.org/Magick++/ Magick++],对于 C 是 [http://imagemagick.org/script/magick-wand.php MagickWand] 3186 | 3187 |

Boost.GIL(Generic Image Library)

3188 | 3189 | Docs:[http://boost.org/libs/gil] 3190 | 3191 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,实现了图像处理功能。 3192 | 3193 | 代码示例——调整图像尺寸 3194 | 3195 | #include 3196 | #include 3197 | #include 3198 | #include 3199 | #include 3200 | 3201 | using namespace boost::gil; 3202 | 3203 | rgb8_image_t img; 3204 | jpeg_read_image("input.jpg", img); 3205 | 3206 | // Scale the image to 100x100 pixels using bilinear resampling 3207 | rgb8_image_t square(100, 100); 3208 | resize_view(const_view(img), view(square), bilinear_sampler()); 3209 | jpeg_write_view("output.jpg", const_view(square)); 3210 | 3211 | 3212 |

Dlib

3213 | 3214 | Docs:[http://dlib.net/imaging.html] 3215 | 3216 | Dlib 前面已经介绍过。它提供了常见的图像处理功能(旋转、剪切、拉伸、过滤)。 3217 | 3218 | == 13.2 图像格式转换 == 3219 | 3220 |

ImageMagick

3221 | 3222 | ImageMagick 前面已经介绍过。它支持非常多的图片格式([http://imagemagick.org/script/formats.php 清单]),基本上你听说过的,它都支持。甚至包括 Postscript 和 PDF。 3223 | 3224 | 在支持的格式中,它可以实现其中几十种格式的相互转换。 3225 | 3226 | == 13.3 图像渲染 == 3227 | 3228 |

Cairo

3229 | 3230 | Home:[http://cairographics.org/] 3231 | 3232 | Links:[https://en.wikipedia.org/wiki/Cairo_%28graphics%29 Wikipedia] [https://zh.wikipedia.org/wiki/Cairo_(%E7%B9%AA%E5%9C%96) 维基百科] 3233 | 3234 | 它提供了矢量图像的渲染功能。支持多种后端输出(Win32 GDI、OpenGL、Xlib、XCB、PDF、PNG、SVG ......)。 3235 | 3236 | 基于 C 语言开发,提供多种语言绑定(C++、Java、C#、Python、Ruby、Perl、Scheme、Smalltalk)。 3237 | 3238 |

cairomm

3239 | 3240 | Home:[http://cairographics.org/cairomm/] 3241 | 3242 | 这是针对 Cairo 的 C++ 封装库。 3243 | 3244 |

Skia

3245 | 3246 | Home:[https://github.com/google/skia] 3247 | 3248 | Links:[https://en.wikipedia.org/wiki/Skia_Graphics_Engine Wikipedia] [https://zh.wikipedia.org/wiki/Skia_Graphics_Library 维基百科] 3249 | 3250 | 它是 Google 基于 C++ 开发的图像渲染库。支持多种后端输出(rasterization、OpenGL、PDF、SVG、SWF ......)。 3251 | 3252 | 原先由 Skia 公司开发,后来该公司被 Google 收购。被用于 Android、Chrome、Chrome OS、Firefox 等知名开源项目。 3253 | 3254 |

PBRT(Physically Based Rendering Toolkit)

3255 | 3256 | Home:[http://pbrt.org/] 3257 | 3258 | 基于光线追踪的物理渲染系统,采用 C++ 开发。 3259 | 3260 | == 13.4 计算机视觉 == 3261 | 3262 |

OpenCV

3263 | 3264 | Home:[http://opencv.org/] 3265 | 3266 | Links:[https://en.wikipedia.org/wiki/OpenCV Wikipedia] [https://zh.wikipedia.org/wiki/OpenCV 维基百科] 3267 | 3268 | 它是一个跨平台的计算机视觉库,由 Intel 发起并参与开发。开发语言是 C 和 C++。 3269 | 3270 | 提供其它编程语言(Python、Java、MATLAB/OCTAVE ...)的 API 绑定。 3271 | 3272 | ---- 3273 | 3274 | = 14 多媒体 = 3275 | 3276 | == 14.1 多媒体框架 == 3277 | 3278 |

FFmpeg

3279 | 3280 | Home:[http://ffmpeg.org/] 3281 | 3282 | Links:[https://en.wikipedia.org/wiki/FFmpeg Wikipedia] [https://zh.wikipedia.org/wiki/FFmpeg 维基百科] 3283 | 3284 | 名气非常大的开源多媒体框架,基于 C 和汇编开发,支持多种操作系统。 3285 | 3286 | 另外,该开源项目还提供了若干命令行工具,包含了一些辅助功能。 3287 | 3288 | * ffmpeg 格式转换工具 3289 | 3290 | * ffplay 简化版的播放器 3291 | 3292 | * ffserver 流媒体服务器 3293 | 3294 | * ffprobe 显示多媒体文件信息 3295 | 3296 | 几个知名的开源播放器(VLC、MPC-HC、xine)用到它,Google Chrome 也用到它。 3297 | 3298 |

Libav

3299 | 3300 | Home:[http://libav.org/] 3301 | 3302 | Links:[https://en.wikipedia.org/wiki/Libav Wikipedia] 3303 | 3304 | 它是2011年从 FFmpeg 派生出来的。基于 C 语言开发,支持多种操作系统。 3305 | 3306 | == 14.2 视频库 == 3307 | 3308 |

libavcodec

3309 | 3310 | Home:[http://ffmpeg.org/] 3311 | 3312 | 它来自于 FFmpeg 社区,基于 C 语言实现,提供了多种视频格式和音频格式的编码/解码功能。 3313 | 3314 | 由于 Libav 从 FFmpeg 分裂出来,Libav 下也带有一个同名的库。 3315 | 3316 | == 14.3 音频库 == 3317 | 3318 |

PortMedia & PortAudio

3319 | 3320 | Home:[http://www.portaudio.com/] 3321 | 3322 | Links:[https://en.wikipedia.org/wiki/PortAudio Wikipedia] 3323 | 3324 | PortAudio 是 PortMedia 的组成部分,提供了音频的播放和录制功能。支持多种底层 API(ALSA、DirectSound、WASAPI、ASIO...) 3325 | 3326 |

OpenAL

3327 | 3328 | Home:[http://www.openal.org/] 3329 | 3330 | Links:[https://en.wikipedia.org/wiki/OpenAL Wikipedia] [https://zh.wikipedia.org/wiki/OpenAL 维基百科] 3331 | 3332 | C 语言开发的 3D 音效库,跨平台。最初由 Loki Software 开发。Loki 倒闭以后,这个项目由开源社区继续维护。 3333 | 3334 | ---- 3335 | 3336 | = 15 游戏 = 3337 | 3338 | == 15.1 综合性的游戏引擎 == 3339 | 3340 |

id Tech 系列

3341 | 3342 | Links:[https://en.wikipedia.org/wiki/Id_Tech Wikipedia] 3343 | 3344 | 这个系列来自于大名鼎鼎的 [https://en.wikipedia.org/wiki/Id_Software id Software 公司],由同样大名鼎鼎约翰·卡马克打造。 3345 | 3346 | 第一代诞生于1993年,是 DOS 时代的经典。 3347 | 3348 | 原先基于 C 和 汇编开发,从 id Tech 4 开始改用 C++ 开发。 3349 | 3350 | * id Tech 1——俗称:Doom 引擎 3351 | 3352 | * id Tech 2(Quake)——俗称:Quake 引擎 3353 | 3354 | * id Tech 2(Quake II)——俗称:Quake II 引擎 3355 | 3356 | * id Tech 3——俗称:Quake III 引擎 3357 | 3358 | * id Tech 4——俗称:Doom 3 引擎 3359 | 3360 |

Crystal Space

3361 | 3362 | Home:[http://www.crystalspace3d.org/] 3363 | 3364 | Links:[https://en.wikipedia.org/wiki/Crystal_Space Wikipedia] 3365 | 3366 | 以 C++ 编写,功能包括:2D 和 3D 渲染、音效、AI... 它的物理引擎基于 ODE 和 Bullet 3367 | 3368 |

Blender Game Engine

3369 | 3370 | Home:[http://www.blender.org/] 3371 | 3372 | Links:[https://en.wikipedia.org/wiki/Game_Blender Wikipedia] [https://zh.wikipedia.org/wiki/Game_Blender 维基百科] 3373 | 3374 | 它是 [https://en.wikipedia.org/wiki/Blender_%28software%29 Blender] 的组成部分,以 C++ 编写,使用 Python 脚本扩展。功能包括:3D 渲染、碰撞检测、角色编辑器、音效、网络通讯、AI、... 3375 | 3376 |

Panda3D

3377 | 3378 | Home:[http://www.panda3d.org/] 3379 | 3380 | Links:[https://en.wikipedia.org/wiki/Panda3D Wikipedia] 3381 | 3382 | 以 C++ 编写,用 Python 脚本扩展。虽然它的名字有“3D”,但它不仅仅是 3D 引擎,还包括了其它功能(碰撞检测、音效、关卡编辑器...)。 3383 | 3384 | == 15.2 3D 渲染引擎 == 3385 | 3386 |

OGRE

3387 | 3388 | Home:[http://www.ogre3d.org/] 3389 | 3390 | Links:[https://en.wikipedia.org/wiki/OGRE Wikipedia] [https://zh.wikipedia.org/wiki/OGRE 维基百科] 3391 | 3392 | 著名的 3D 渲染引擎,C++ 开发,诞生于2005年。支持很多操作系统(包括两大手机操作系统)。很多商业游戏用到它。 3393 | 3394 | 支持其它编程语言(Python、Ruby、Perl)的 API 绑定。支持 JVM 和 dotNet 平台。 3395 | 3396 |

Mesa 3D

3397 | 3398 | Home:[http://mesa3d.org/] 3399 | 3400 | Links:[https://en.wikipedia.org/wiki/Mesa_%28computer_graphics%29 Wikipedia] [https://zh.wikipedia.org/wiki/Mesa_3D 维基百科] 3401 | 3402 | 使用 C 语言开发,它是针对 OpenGL 规范的【纯软件】实现(大部分 OpenGL 的实现都用到了显卡硬件)。 3403 | 3404 | == 15.3 物理引擎 == 3405 | 3406 |

Bullet

3407 | 3408 | Home:[http://www.bulletphysics.org/] 3409 | 3410 | Links:[https://en.wikipedia.org/wiki/Bullet_%28software%29 Wikipedia] [https://zh.wikipedia.org/wiki/Bullet 维基百科] 3411 | 3412 | 采用 C 和 C++ 开发。电影《2012》用到它,游戏“侠盗猎车手”、“荒野大镖客”用到它。 3413 | 3414 |

Box2D

3415 | 3416 | Home:[http://www.box2d.org/] 3417 | 3418 | Links:[https://en.wikipedia.org/wiki/Box2D Wikipedia] [https://zh.wikipedia.org/wiki/Box2D 维基百科] 3419 | 3420 | 基于 C++ 开发的2维物理引擎。“愤怒的小鸟”用到它。 3421 | 3422 |

ODE(Open Dynamics Engine)

3423 | 3424 | Home:[http://www.ode.org/] 3425 | 3426 | Links:[https://en.wikipedia.org/wiki/Open_Dynamics_Engine Wikipedia] [https://zh.wikipedia.org/wiki/Open_Dynamics_Engine 维基百科] 3427 | 3428 | 诞生于2001年,采用 C 和 C++ 开发。 3429 | 3430 |

Newton Game Dynamics

3431 | 3432 | Home:[http://www.newtondynamics.com/] 3433 | 3434 | Links:[https://en.wikipedia.org/wiki/Newton_Game_Dynamics Wikipedia] 3435 | 3436 | 基于 C++ 开发。 3437 | 3438 | ---- 3439 | 3440 | = 16 数值运算 & 科学计算 = 3441 | 3442 | == 16.1 综合性的库 == 3443 | 3444 |

GSL(GNU Scientific Library)

3445 | 3446 | Home:[https://www.gnu.org/software/gsl/] 3447 | 3448 | Links:[https://en.wikipedia.org/wiki/GNU_Scientific_Library Wikipedia] 3449 | 3450 | 由 GNU 官方提供,包括:复数、多项式、矩阵、线性代数、特征向量、快速傅里叶变换、统计、模拟退火...... 3451 | 3452 | 代码示例——贝塞尔函数 3453 | 3454 | #include 3455 | #include 3456 | 3457 | double x = 5.0; 3458 | double y = gsl_sf_bessel_J0(x); 3459 | printf("J0(%g) = %.18e\n", x, y); 3460 | 3461 | 3462 | == 16.2 有理数 == 3463 | 3464 |

Boost.Rational

3465 | 3466 | Docs:[http://boost.org/libs/rational] 3467 | 3468 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“有理数”的功能。 3469 | 3470 | == 16.3 高精度数值运算 == 3471 | 3472 |

GMP(GNU Multiple Precision)

3473 | 3474 | Home:[https://gmplib.org/] 3475 | 3476 | Links:[https://en.wikipedia.org/wiki/GNU_Multiple_Precision_Arithmetic_Library Wikipedia] [https://zh.wikipedia.org/wiki/GNU%E5%A4%9A%E9%87%8D%E7%B2%BE%E5%BA%A6%E8%BF%90%E7%AE%97%E5%BA%93 维基百科] 3477 | 3478 | 基于 C 语言的高精度数值运算库,诞生于1991年,非常老牌。 3479 | 3480 | 代码示例——大整数相乘 3481 | 3482 | #include 3483 | #include 3484 | 3485 | mpz_t x,y,result; 3486 | 3487 | mpz_init_set_str(x, "7612058254738945", 10); 3488 | mpz_init_set_str(y, "9263591128439081", 10); 3489 | mpz_init(result); 3490 | 3491 | mpz_mul(result, x, y); 3492 | gmp_printf("%Zd\n", result); 3493 | 3494 | /* free used memory */ 3495 | mpz_clear(x); 3496 | mpz_clear(y); 3497 | mpz_clear(result); 3498 | 3499 | 3500 |

Boost.Multiprecision

3501 | 3502 | Docs:[http://boost.org/libs/multiprecision] 3503 | 3504 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,实现了高精度数值运算。它还提供了针对 GMP 的数据类型的封装。 3505 | 3506 | == 16.4 矩阵 == 3507 | 3508 |

Boost.uBLAS.Matrix

3509 | 3510 | Docs:[http://boost.org/libs/numeric/ublas/doc/matrix.html] 3511 | 3512 | Boost 前面已经介绍过。这是 Boost 提供的矩阵模板类。 3513 | 3514 | 代码示例 3515 | 3516 | #include 3517 | #include 3518 | 3519 | using namespace boost::numeric::ublas; 3520 | 3521 | matrix m(3, 3); 3522 | for(unsigned i=0; i 3528 | 3529 |

Dlib

3530 | 3531 | Docs:[http://dlib.net/linear_algebra.html#matrix] 3532 | 3533 | Dlib 前面已经介绍过。它提供了一个矩阵类。 3534 | 3535 | == 16.5 线性代数 == 3536 | 3537 |

Boost.uBLAS

3538 | 3539 | Docs:[http://boost.org/libs/numeric/ublas] 3540 | 3541 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,实现了 BLAS 的1、2、3级。 3542 | 3543 | 代码示例——计算矩阵与矢量的乘积 3544 | 3545 | #include 3546 | #include 3547 | #include 3548 | #include 3549 | 3550 | using namespace std; 3551 | using namespace boost::numeric::ublas; 3552 | 3553 | vector v(2); 3554 | v(0) = 1; v(1) = 2; 3555 | 3556 | matrix m(2,2); 3557 | m(0,0) = 0; m(0,1) = 1; 3558 | m(1,0) = 2; m(1,1) = 3; 3559 | 3560 | vector v2 = prod(m, v); 3561 | cout << v2 << endl; 3562 | 3563 | 3564 |

Blitz++

3565 | 3566 | Home:[http://blitz.sourceforge.net/] 3567 | 3568 | Links:[https://en.wikipedia.org/wiki/Blitz%2B%2B Wikipedia] 3569 | 3570 | 它是基于 C++ 实现的。其特色是:采用“模板元编程”的技术进行编译时计算,从而优化了性能。 3571 | 3572 |

Armadillo

3573 | 3574 | Home:[http://arma.sourceforge.net/] 3575 | 3576 | Links:[https://en.wikipedia.org/wiki/Armadillo_%28C%2B%2B_library%29 Wikipedia] 3577 | 3578 | 类似 Blitz++,Armadillo 也用了“模板元编程”的技术。 3579 | 3580 | 代码示例 3581 | 3582 | #include 3583 | #include 3584 | 3585 | using namespace std; 3586 | using namespace arma; 3587 | 3588 | vec v; 3589 | v << 2.0 << 5.0 << 2.0; 3590 | 3591 | // endr represents the end of a row in a matrix 3592 | mat m; 3593 | m << 1.0 << 2.0 << endr 3594 | << 2.0 << 3.0 << endr 3595 | << 1.0 << 3.0 << endr; 3596 | 3597 | cout << "Least squares solution:" << endl << solve(m,v) << endl; 3598 | 3599 | 3600 |

Dlib

3601 | 3602 | Docs:[http://dlib.net/linear_algebra.html] 3603 | 3604 | Dlib 前面已经介绍过。它提供了线性代数相关的封装类。 3605 | 3606 | ---- 3607 | 3608 | = 17 跨语言编程 = 3609 | 3610 | == 17.1 整合多种语言的库 == 3611 | 3612 |

SWIG

3613 | 3614 | Home:[http://swig.org/] 3615 | 3616 | Links:[https://en.wikipedia.org/wiki/SWIG Wikipedia] 3617 | 3618 | 这是一个很老牌的、有名气的工具,它可以把多种语言(Java、Python、C#、Ruby、PHP、Perl、Lua、Go ......)整合到 C/C++ 中。 3619 | 3620 | 整合之后,你的 C/C++ 程序就可以享受到其它这些语言的特性啦,非常爽! 3621 | 3622 | == 17.2 整合单一语言的库 == 3623 | 3624 | === 17.2.1 整合 Python 语言 === 3625 | 3626 |

Boost.Python

3627 | 3628 | Docs:[http://boost.org/libs/python] 3629 | 3630 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,实现了 C++ 代码和 Python 代码的互操作。 3631 | 3632 | 代码示例——Hello world 3633 | 3634 | // 这是一个标准的 C 函数 3635 | const char* greet() 3636 | { 3637 | return "Hello, world"; 3638 | } 3639 | 3640 | // 使用如下代码对上述函数进行包装 3641 | #include 3642 | BOOST_PYTHON_MODULE(hello_ext) 3643 | { 3644 | using namespace boost::python; 3645 | def("greet", greet); 3646 | } 3647 | 3648 | // 以下是调用该模块的 Python 代码 3649 | // import hello_ext 3650 | // print(hello_ext.greet()) 3651 | 3652 | 3653 |

Cython

3654 | 3655 | Home:[http://cython.org/] 3656 | 3657 | Links:[https://en.wikipedia.org/wiki/Cython Wikipedia] 3658 | 3659 | Cython 提供了一种机制(编译器)编译 Python 代码为【原生代码】。编译后的原生代码是个 Python 的 module(扩展名是 pyd 或 so),可以在常规的 Python 环境中用 import 语句加载。如此一来,既得到了类似 C/C++ 的高性能,又保留了 Python 语法的简介性。 3660 | 3661 | 另外,它也提供了把 C/C++ 代码编译为 Python 模块的机制。 3662 | 3663 | === 17.2.2 整合 JavaScript 语言 === 3664 | 3665 |

V8

3666 | 3667 | Home:[https://github.com/v8/v8] 3668 | 3669 | Links:[https://en.wikipedia.org/wiki/Chrome_V8 Wikipedia] 3670 | 3671 | 这就是大名鼎鼎的 V8 引擎,Google 公司开发,C++ 编写,被用于 Chrome 浏览器。 3672 | 3673 | 既然用于 Chrome 浏览器,显然【完整地】支持了 JS 语言的规范(ECMA-262)。 3674 | 3675 | 它既可以独立运行,也可以嵌入到 C++ 程序中。 3676 | 3677 | 代码示例——Hello world 3678 | 3679 | #include 3680 | #include 3681 | #include 3682 | #include 3683 | #include 3684 | 3685 | int main(int argc, char* argv[]) 3686 | { 3687 | // Initialize V8. 3688 | v8::V8::InitializeICUDefaultLocation(argv[0]); 3689 | v8::V8::InitializeExternalStartupData(argv[0]); 3690 | std::unique_ptr platform = v8::platform::NewDefaultPlatform(); 3691 | v8::V8::InitializePlatform(platform.get()); 3692 | v8::V8::Initialize(); 3693 | 3694 | // Create a new Isolate and make it the current one. 3695 | v8::Isolate::CreateParams create_params; 3696 | create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator(); 3697 | v8::Isolate* isolate = v8::Isolate::New(create_params); 3698 | 3699 | { 3700 | v8::Isolate::Scope isolate_scope(isolate); 3701 | // Create a stack-allocated handle scope. 3702 | v8::HandleScope handle_scope(isolate); 3703 | // Create a new context. 3704 | v8::Local context = v8::Context::New(isolate); 3705 | // Enter the context for compiling and running the hello world script. 3706 | v8::Context::Scope context_scope(context); 3707 | // Create a string containing the JavaScript source code. 3708 | v8::Local source = 3709 | v8::String::NewFromUtf8(isolate, "'Hello World!'", 3710 | v8::NewStringType::kNormal).ToLocalChecked(); 3711 | // Compile the source code. 3712 | v8::Local script = v8::Script::Compile(context, source).ToLocalChecked(); 3713 | // Run the script to get the result. 3714 | v8::Local result = script->Run(context).ToLocalChecked(); 3715 | // Convert the result to an UTF8 string and print it. 3716 | v8::String::Utf8Value utf8(isolate, result); 3717 | printf("%s\n", *utf8); 3718 | } 3719 | 3720 | // Dispose the isolate and tear down V8. 3721 | isolate->Dispose(); 3722 | v8::V8::Dispose(); 3723 | v8::V8::ShutdownPlatform(); 3724 | delete create_params.array_buffer_allocator; 3725 | return 0; 3726 | } 3727 | 3728 | 3729 |

nbind

3730 | 3731 | Home:[https://github.com/charto/nbind] 3732 | 3733 | 把 C++ 代码编译为 JS 的 package。编译方式支持“原生二进制”或“asm.js”。 3734 | 3735 | 编译需要依赖 Node.js,运行环境支持 Node.js 或浏览器。 3736 | 3737 | 代码示例——C++ 代码 3738 | 3739 | #include 3740 | #include 3741 | 3742 | struct Greeter 3743 | { 3744 | static void sayHello(std::string name) 3745 | { 3746 | std::cout << "Hello, " << name << "\n"; 3747 | } 3748 | }; 3749 | 3750 | // 建立绑定 3751 | #include 3752 | 3753 | NBIND_CLASS(Greeter) 3754 | { 3755 | method(sayHello); 3756 | } 3757 | 3758 | 3759 | 代码示例——node.js 环境调用代码 3760 | 3761 | var nbind = require("nbind"); 3762 | var lib = nbind.init().lib; 3763 | lib.Greeter.sayHello("you"); 3764 | 3765 | 3766 | 代码示例——浏览器环境调用代码 3767 | 3768 | 3769 | 3778 | 3779 | 3780 | ---- 3781 | 3782 | = 18 (其它) = 3783 | 3784 | 一些不方便归类的,暂时放到这里。 3785 | 3786 | == 18.1 词法分析 & 语法分析 == 3787 | 3788 |

Boost.Spirit

3789 | 3790 | Docs:[http://boost.org/libs/spirit] 3791 | 3792 | Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“基于 EBNF 的解析器框架”。 3793 | 3794 | -------------------------------------------------------------------------------- /libs/python.wiki: -------------------------------------------------------------------------------- 1 |

Python 开源库及示例代码

2 | 3 | = = 4 | 5 | = 说明 = 6 | 7 | 本页面汇总俺收集的各种 Python 代码库,不定期更新。 8 | 9 | 本页面列出的各种 Python 库/模块,如果注明了官网的网址,说明这个库是第三方的;否则就是 Python 语言内置的标准库。 10 | 11 | 如果你发现本页面的开源库有错漏之处,非常欢迎给俺提供反馈——有 GitHub 帐号的同学,可以[https://github.com/programthink/opensource/issues 给俺发 issue];没帐号的同学,可以去[https://program-think.blogspot.com/ 俺博客]留言。 12 | 13 | ---- 14 | 15 | = 1 算法 = 16 | 17 | == 1.1 字符串 == 18 | 19 | === 1.1.1 正则表达式 === 20 | 21 |

re

22 | 23 | 【标准库】 24 | 25 | 提供基于正则的匹配和替换。 26 | 27 | === 1.1.2 字符集 === 28 | 29 |

chardet

30 | 31 | Home:[https://github.com/erikrose/chardet] 32 | 33 | chardet 可以猜测任意一段文本的字符集编码。对于编码类型未知的文本,它会很有用。 34 | 35 | chardet 既可以作为模块来使用,也可以作为命令行工具来使用。 36 | 37 | 代码示例 38 | 39 | import chardet 40 | print(chardet.detect(bytes)) 41 | 42 | 43 | === 1.1.3 (其它) === 44 | 45 |

StringIO & cStringIO

46 | 47 | 【标准库】 48 | 49 | 以读写文件的方式来操作字符串(有点类似于内存文件)。 50 | 51 | cStringIO 是 C 语言实现的,性能更高;而 StringIO 是 Python 实现的,提供 Unicode 兼容性。 52 | 53 |

difflib

54 | 55 | 【标准库】 56 | 57 | 可以对两个字符串进行“按行”比较,其功能类似于命令行的 diff。 58 | 59 | 另外还支持“最佳匹配”功能——对给定的字符串 s 和字符串列表 l,在 l 里面找到最接近 s 的字符串。 60 | 61 | == 1.2 编码 & 解码 == 62 | 63 | === 1.2.1 base64 === 64 | 65 | [https://en.wikipedia.org/wiki/Base64 Base64] 是一组编码算法的总称。用于把二进制数据编码为文本。 66 | 67 |

base64

68 | 69 | 【标准库】 70 | 71 | 提供 Base16、Base32、Base64 格式的编码和解码。 72 | 73 | === 1.2.2 UUencode === 74 | 75 | [https://en.wikipedia.org/wiki/Uuencode UUencode] 出现于早期的 Unix 系统。用于把二进制编码为文本,以便通过邮件系统发送。 76 | 77 |

uu

78 | 79 | 【标准库】 80 | 81 | 提供 UUencode 格式的编码和解码。 82 | 83 | === 1.2.3 BinHex === 84 | 85 | [https://en.wikipedia.org/wiki/BinHex BinHex] 起先用于 Mac OS 系统,类似于 UUencode。 86 | 87 |

binhex

88 | 89 | 【标准库】 90 | 91 | 提供 BinHex 格式的编码和解码。 92 | 93 | == 1.3 数学类 == 94 | 95 |

math

96 | 97 | 【标准库】 98 | 99 | 顾名思义,这个标准库封装了常用的数学函数(开方、指数、对数、三角函数......)。 100 | 101 |

random

102 | 103 | 【标准库】 104 | 105 | 顾名思义,这个标准库是用来进行随机数生成滴。 106 | 107 | 代码示例——生成 0-100 的随机数 108 | 109 | import random 110 | random.seed() 111 | random.randint(0, 100) 112 | 113 | 114 |

fractions

115 | 116 | 【标准库】 117 | 118 | 封装了跟有理数(分数)相关的运算 119 | 120 | == 1.4 容器 == 121 | 122 |

pygtrie

123 | 124 | Home:[https://github.com/google/pytrie] 125 | 126 | 这是 Google 实现的 [https://zh.wikipedia.org/wiki/Trie trie](前缀树/字典树)封装库。 127 | 128 | ---- 129 | 130 | = 2 跨语言编程 = 131 | 132 | Python 可以很容易地跟其它编程语言整合。整合之后,就可以在 Python 代码中使用其它编程语言的函数、模块、库,非常爽! 133 | == 2.1 整合 C & C++ == 134 | 135 |

ctypes

136 | 137 | ctypes 在 Python 2.5 版本加入到标准库中。 138 | 139 | 通过它,你可以很方便地调用 C/C++ 动态库导出的函数,可以在 Python 中使用各种 C/C++ 的数据类型(包括“指针”和“引用”)。 140 | 141 | 代码示例——调用 Linux/Unix 系统的标准 C 函数,获取当前时间 142 | 143 | from ctypes import * 144 | 145 | libc = CDLL("libc.so.6") 146 | time = libc.time(None) 147 | 148 | 149 | 代码示例——调用 Windows 系统的 API,弹出消息提示框 150 | 151 | from ctypes import c_int, WINFUNCTYPE, windll 152 | from ctypes.wintypes import HWND, LPCSTR, UINT 153 | 154 | prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT) 155 | paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0) 156 | MessageBox = prototype(("MessageBoxA", windll.user32), paramflags) 157 | MessageBox(text="Hello, world", flags=2) 158 | 159 | 160 |

SWIG(Simplified Wrapper and Interface Generator)

161 | 162 | Home:[http://swig.org/] 163 | 164 | Links:[https://en.wikipedia.org/wiki/SWIG Wikipedia] 165 | 166 | 这是一个很老牌的、有名气的工具,它可以把多种语言(Java、Python、C#、Ruby、PHP、Perl、Lua、Go ...)整合到 C/C++ 中。 167 | 168 |

Cython

169 | 170 | Home:[http://cython.org/] 171 | 172 | 这个工具可以让你用 Python 的语法写扩展模块的代码,然后它帮你把 Python 代码编译为本地动态库(机器码)。 173 | 174 | 用它编译出来的扩展模块,其性能跟 C/C++ 编写的扩展模块相当。 175 | 176 | == 2.2 整合 JVM 平台 == 177 | 178 |

Jython

179 | 180 | Home:[http://www.jython.org/] 181 | 182 | Links:[https://en.wikipedia.org/wiki/Jython Wikipedia] [https://zh.wikipedia.org/wiki/Jython 维基百科] 183 | 184 | 通过 Jython 可以让 Python 代码运行在 JVM 上,并且可以调用其它的 JVM 语言的代码(比如 Java、Scala) 185 | 186 | == 2.3 整合 dotNet 平台 == 187 | 188 |

IronPython

189 | 190 | Home:[http://ironpython.net/] 191 | 192 | Links:[https://en.wikipedia.org/wiki/IronPython Wikipedia] [https://zh.wikipedia.org/wiki/IronPython 维基百科] 193 | 194 | 通过 IronPython 可以让 Python 代码运行在 dotNET 平台上,并且可以调用其它的 dotNET 语言的代码(C#、F#、VB.Net ...) 195 | 196 | == 2.4 整合 Go == 197 | 198 |

gopy

199 | 200 | Home:[https://github.com/go-python/gopy] 201 | 202 | gopy 可以把 Go 源代码编译为 Python 的一个 module。 203 | 204 | 它提供了两种方式(命令行、Python 库)来实现:Go 源码编译为 Python 模块。 205 | 206 | == 2.5 整合 Objective-C == 207 | 208 |

PyObjC

209 | 210 | Home:[http://pyobjc.sourceforge.net/] 211 | 212 | 这是用 Python 封装 Mac OS X 上的 Objective-C 库。 213 | 214 | ---- 215 | 216 | = 3 操作系统 = 217 | 218 | == 3.1 文件和目录操作 == 219 | 220 |

os

221 | 222 | 【标准库】 223 | 224 | 这是非常基本的标准库,提供了常见的操作系统相关功能,很多功能是针对文件系统。 225 | 226 |

shutil

227 | 228 | 【标准库】 229 | 230 | 相对于 os 而言,shutil 提供了一些比较高级的文件和目录操作(目录递归复制、目录递归删除、目录压缩打包...) 231 | 232 | 代码示例——递归删除某个目录 233 | 234 | import shutil 235 | shutil.rmtree(xxxx) 236 | 237 | 238 |

glob

239 | 240 | 【标准库】 241 | 242 | 用于查找文件,【支持通配符】(* 和 ?) 243 | 244 | 代码示例——获取当前目录所有 txt 文件 245 | 246 | import glob 247 | for file in glob.glob("./*.txt") : 248 | print(file) 249 | 250 | 251 |

fnmatch

252 | 253 | 【标准库】 254 | 255 | 用于匹配文件名(支持通配符,类似上面的 glob) 256 | 257 | 代码示例——列出当前目录所有 txt 文件 258 | 259 | import os, fnmatch 260 | 261 | for file in os.listdir(".") : 262 | if fnmatch.fnmatch(file, "*.txt") : 263 | print(file) 264 | 265 | 266 |

tempfile

267 | 268 | 【标准库】 269 | 270 | 使用它可以安全地生成临时文件或临时目录。 271 | 272 | 273 | 274 | == 3.2 线程 == 275 | 276 |

threading

277 | 278 | 【标准库】 279 | 280 | 提供了比较高层的线程封装 API。它本身包含了线程同步/互斥的机制。 281 | 282 | 代码示例——基于“函数”的线程 283 | 284 | import threading 285 | import time 286 | 287 | def my_thread() : 288 | print("Thread started!") 289 | time.sleep(3) 290 | print("Thread finished!") 291 | 292 | threading.Thread(target=my_thread).start() 293 | 294 | 295 | 代码示例——基于“类”的线程 296 | 297 | import threading 298 | import time 299 | from __future__ import print_function 300 | 301 | class MyThread(threading.Thread) : 302 | def run(self) : 303 | print("{} started!".format(self.getName())) 304 | time.sleep(3) 305 | print("{} finished!".format(self.getName())) 306 | 307 | if __name__ == "__main__" : 308 | for n in range(10) : 309 | mythread = MyThread(name = "Thread-{}".format(n + 1)) 310 | mythread.start() 311 | time.sleep(1) 312 | 313 | 314 | == 3.3 进程 == 315 | 316 |

subprocess

317 | 318 | 【标准库】 319 | 320 | 用于进程管理,可以启动子进程,通过标准输入输出跟子进程交互。 321 | 322 | 代码示例——启动命令行进程,并获取该进程的标准输出 323 | 324 | import subprocess 325 | output = subprocess.check_output(["dir"]) # 获取当前目录的内容 326 | output = subprocess.check_output(["netstat", "-an"]) # 获取当前网络链接 327 | 328 | 329 |

multiprocessing

330 | 331 | 【标准库】 332 | 333 | 它是 2.6 版本加入到标准库的,其 API 接口的风格类似于 threading 模块。 334 | 335 | 它本身包含了进程同步/互斥的机制。 336 | 337 | 代码示例——利用其 Lock 机制,确保多个子进程的标准输出不会混杂(每次只有一个进程调用 print)。 338 | 339 | from multiprocessing import Process, Lock 340 | 341 | def f(lock, n) : 342 | lock.acquire() 343 | print("hello world %d" % n) 344 | lock.release() 345 | 346 | if __name__ == "__main__" : 347 | lock = Lock() 348 | for num in range(10): 349 | Process(target=f, args=(lock, num)).start() 350 | 351 | 352 |

sh

353 | 354 | Home:[https://github.com/amoffat/sh] 355 | 356 | 这个项目可以用来取代标准库中的 subprocess;同时兼容 Python2 和 Python3。 357 | 358 | 使用它可以写出比 subprocess 更简洁、更优雅的代码。 359 | 360 | 代码示例——获取命令输出 361 | 362 | from sh import ifconfig 363 | print(ifconfig("wlan0")) 364 | 365 | 366 | 代码示例——命令行参数 367 | 368 | from sh import curl 369 | # 传统风格 370 | curl("https://program-think.blogspot.com/", "-o", "test.html", "--silent") 371 | # 命名参数风格 372 | curl("https://program-think.blogspot.com/", o="test.html", silent=True) 373 | 374 | 375 | 代码示例——管道 376 | 377 | from sh import ls, wc 378 | print(wc(ls("/etc", "-1"), "-l")) 379 | 380 | 381 | == 3.4 本地进程间通信(IPC) == 382 | 383 |

mmap

384 | 385 | 【标准库】 386 | 387 | 提供了内存映射文件的支持。 388 | 389 | 代码示例——利用 mmap 在父子进程间交换数据 390 | 391 | import os 392 | import mmap 393 | 394 | map = mmap.mmap(-1, 13) 395 | map.write("Hello, world") 396 | 397 | pid = os.fork() 398 | if pid == 0 : # 子进程 399 | map.seek(0) 400 | print(map.readline()) 401 | map.close() 402 | 403 | 404 |

signal

405 | 406 | 【标准库】 407 | 408 | 用于进程信号处理的标准库(主要用于 Linux & UNIX 系统)。 409 | 410 | == 3.5 操作硬件 == 411 | 412 |

keyboard

413 | 414 | Home:[https://github.com/boppreh/keyboard] 415 | 416 | 顾名思义,这个库让你可以进行各种键盘相关的操作,包括:模拟按键、键盘钩子(hook),按键记录及重放。 417 | 418 | 支持复杂的组合键。纯 python 代码代码,同时支持 Windows 和 Linux。 419 | 420 | 代码示例 421 | 422 | import keyboard 423 | 424 | # 模拟按键。 425 | keyboard.press_and_release("shift+s, space") 426 | 427 | # 模拟按键,并执行相应代码。 428 | keyboard.add_hotkey("page up, page down", lambda: keyboard.write("xxxx")) 429 | 430 | # 等待特定按键,然后继续执行。 431 | keyboard.wait("esc") 432 | 433 | # 记录按键,直到用户按了 ESC;然后以3倍速重放刚才记录的按键。 434 | recorded = keyboard.record(until="esc") 435 | keyboard.play(recorded, speed_factor=3) 436 | 437 | 438 | == 3.6 获取系统信息 == 439 | 440 |

sys

441 | 442 | 【标准库】 443 | 444 | 这个模块可供访问由解释器使用或维护的变量和与解释器进行交互的函数。 445 | 446 | 代码示例 447 | 448 | sys.argv # 命令行参数 List,第一个元素是程序本身路径 449 | sys.exit(0) # 退出程序,正常退出时用 0 表示退出码 450 | sys.version # 获取 Python 解释程序的版本信息 451 | 452 | 453 |

platform

454 | 455 | 【标准库】 456 | 457 | 这个模块提供了很多用于获取操作系统的信息的功能。 458 | 459 | 代码示例 460 | 461 | import platform 462 | 463 | platform.platform() # 获取操作系统名称及版本号,例如:"Windows-7-6.1.7601-SP1" 464 | platform.version() # 获取操作系统版本号,例如:"6.1.7601" 465 | platform.architecture() # 获取操作系统的架构,例如:("32bit", "WindowsPE") 466 | 467 | 468 |

psutil

469 | 470 | Home:[https://github.com/giampaolo/psutil] 471 | 472 | psutil(Python system and process utilities)是一个跨平台的进程管理和系统工具库,可以处理”CPU、内存、磁盘、网络、用户“等信息。 473 | 474 | 主要用于系统资源的监控,分析,以及对进程进行一定的管理。 475 | 476 | 代码示例 477 | 478 | import psutil 479 | 480 | psutil.cpu_count() # 获取 CPU 数量 481 | psutil.cpu_freq() # 获取 CPU 频率 482 | 483 | psutil.virtual_memory() # 获取内存信息 484 | psutil.swap_memory() # 获取交换分区(换页文件)信息 485 | 486 | psutil.disk_partitions() # 获取分区信息 487 | psutil.disk_usage('/') # 获取某分区的使用情况 488 | 489 | psutil.users() # 获取用户信息 490 | 491 | p = psutil.Process(pid) # 根据给定的 pid 获得进程对象 492 | p.name() # 进程名 493 | p.exe() # 可执行程序的全路径 494 | p.cwd() # 进程的当前目录 495 | p.cmdline() # 启动进程的命令行参数 496 | 497 | 498 | == 3.7 Linux & Unix 系统相关 == 499 | 500 |

syslog

501 | 502 | 【标准库】 503 | 504 | 通过它可以很方便地跟 POSIX 的 syslog 服务进行交互。 505 | 506 | == 3.8 Windows 系统相关 == 507 | 508 |

PyWin32

509 | 510 | Home:[http://python.net/crew/mhammond/win32/] 511 | 512 | 这个第三方库封装了 Windows API 及 COM API。通过它可以方便地用 Python 进行 Windows 编程(调用 COM 组件、编写 Windows 服务、等)。 513 | 514 | == 3.9 程序打包 == 515 | 516 |

PyInstaller

517 | 518 | Home:[http://www.pyinstaller.org/] 519 | 520 | PyInstaller 可以把你的 Python 代码制作成独立运行的程序(不依赖 Python 环境就可以运行)。 521 | 522 | 该工具支持多种操作系统,包括:Windows、Linux、Mac OS X、Solaris、AIX、等。 523 | 524 |

py2exe

525 | 526 | Home:[http://www.py2exe.org/] 527 | 528 | Links:[https://en.wikipedia.org/wiki/Py2exe Wikipedia] 529 | 530 | py2exe 的功能类似 PyInstaller,但只支持 Windows 平台。 531 | 532 |

py2app

533 | 534 | Home:[https://bitbucket.org/ronaldoussoren/py2app] 535 | 536 | 它很类似于 [http://www.py2exe.org/ py2exe],差别在于 [http://www.py2exe.org/ py2exe] 支持 Windows 平台,而 [https://bitbucket.org/ronaldoussoren/py2app py2app] 支持 Mac OS X 平台。 537 | 538 |

EasyInstall & Setuptools

539 | 540 | Home:[https://pypi.python.org/pypi/setuptools] 541 | 542 | 这套工具可以帮助你进行第三方库的管理(下载、编译、安装、升级、卸载) 543 | 544 | ---- 545 | 546 | = 4 Web = 547 | 548 | == 4.1 HTTP Client == 549 | 550 |

httplib & httplib2 & http.request & urllib.parse

551 | 552 | 【标准库】 553 | 554 | 这几个库可以进行各种 HTTP 客户端请求(GET、POST、等)。 555 | 556 | Python2 的模块名是 httplib 和 httplib2;到 Python3,模块名改为 http.request 和 urllib.parse 557 | 558 | 代码示例——读取指定 URL 的网页内容 559 | 560 | import urllib 561 | handle = urllib.urlopen("http://www.google.com") 562 | page = handle.read() 563 | handle.close() 564 | 565 | 566 |

Requests

567 | 568 | Home:[http://www.python-requests.org/] 569 | 570 | 这是一个用起来很优雅的库,如其名,封装了 HTTP 请求的功能。 571 | 572 | 代码示例 573 | 574 | >>> r = requests.get('https://api.github.com/user', auth=('user', 'pass')) 575 | >>> r.status_code 576 | 200 577 | >>> r.headers['content-type'] 578 | 'application/json; charset=utf8' 579 | >>> r.encoding 580 | 'utf-8' 581 | >>> r.text 582 | u'{"type":"User"...' 583 | >>> r.json() 584 | {u'private_gists': 419, u'total_private_repos': 77, ...} 585 | 586 | 587 | == 4.2 HTTP Server == 588 | 589 |

SimpleHTTPServer & http.server

590 | 591 | 【标准库】 592 | 593 | 提供轻量级 HTTP Server 的标准库。 594 | 595 | Python2 的模块名叫 SimpleHTTPServer;到 Python3 模块名改为 http.server 596 | 597 | 代码示例——一个极简单的 HTTP 服务 598 | 599 | import SocketServer 600 | import SimpleHTTPServer 601 | 602 | PORT = 8080 603 | Handler = SimpleHTTPServer.SimpleHTTPRequestHandler 604 | httpd = SocketServer.TCPServer(("", PORT), Handler) 605 | print("serving at port %d" % PORT) 606 | httpd.serve_forever() 607 | 608 | 609 | == 4.3 Web 开发框架 == 610 | 611 | (Python 的 Web 框架数不胜数,俺只挑选几个代表性的) 612 |

Django

613 | 614 | Home:[https://www.djangoproject.com/] 615 | 616 | Links:[https://en.wikipedia.org/wiki/Django_(web_framework) Wikipedia] [https://zh.wikipedia.org/wiki/Django 维基百科] 617 | 618 | 在 Python 社区,Django 是目前最有影响力的 Web 开发框架。该框架很重型,内置了 Web 服务端开发常用的组件(比如:ORM、用户管理)。 619 | 620 | Django 应用范围很广,比如 Google 的 Web 开发平台 GAE 就支持它。 621 | 622 | 而且它完全支持前面提到的 Jython 运行环境,可以运行在任何 J2EE 服务器上。 623 | 624 |

TurboGears

625 | 626 | Home:[http://www.turbogears.org/] 627 | 628 | Links:[https://en.wikipedia.org/wiki/TurboGears Wikipedia] [https://zh.wikipedia.org/wiki/TurboGears 维基百科] 629 | 630 | 又一个重型的 Web 开发框架,名气仅次于 Django。 631 | 632 | 它跟 Django 一样,都是“Full-Stack Frameworks”。 633 | 634 |

CherryPy

635 | 636 | Home:[http://www.cherrypy.org/] 637 | 638 | Links:[https://en.wikipedia.org/wiki/CherryPy Wikipedia] 639 | 640 | 轻量级的 Web 框架。某些 Web 框架(比如前面提到的 TurboGears)使用它作为底层。 641 | 642 | 代码示例——Hello world 643 | 644 | import cherrypy 645 | 646 | class HelloWorld(object) : 647 | def index(self) : 648 | return "Hello World!" 649 | index.exposed = True 650 | 651 | cherrypy.quickstart(HelloWorld()) 652 | 653 | 654 |

web.py

655 | 656 | Home:[http://webpy.org/] 657 | 658 | 与前两个(Django、TurboGears)不同,这是一个轻量级的框架。甚至被称为“It's the anti-framework framework.” 659 | 660 | 其作者是大名鼎鼎的黑客 [https://en.wikipedia.org/wiki/Aaron_Swartz Aaron Swartz]。(俺在[http://program-think.blogspot.nl/2013/01/weekly-share-37.html 某篇博文]中悼念过他)。 661 | 662 | 当年 Aaron Swartz 用 web.py 来搭建同样大名鼎鼎的网站 [https://en.wikipedia.org/wiki/Reddit reddit](该网站是 Web 2.0 的标杆)。 663 | 664 | 代码示例——Hello world 665 | 666 | import web 667 | 668 | urls = ( 669 | "/", "index" 670 | ) 671 | 672 | class index : 673 | def GET(self) : 674 | return "Hello, world!" 675 | 676 | if __name__ == "__main__" : 677 | app = web.application(urls, globals()) 678 | app.run() 679 | 680 | 681 |

Flask

682 | 683 | Home:[http://flask.pocoo.org/] 684 | 685 | Links:[https://zh.wikipedia.org/wiki/Flask 维基百科] 686 | 687 | 轻量级 Web 应用框架。基于 Werkzeug WSGI 工具箱和 Jinja2 模板引擎。 688 | 689 | 代码示例——Hello world 690 | 691 | from flask import Flask 692 | app = Flask(__name__) 693 | 694 | app.route("/") 695 | def hello_world() : 696 | return “Hello World!" 697 | 698 | if __name__ == "__main__" : 699 | app.run() 700 | 701 | 702 |

Tornado

703 | 704 | Home:[http://www.tornadoweb.org/] 705 | 706 | Links:[https://zh.wikipedia.org/wiki/Tornado 维基百科] 707 | 708 | 同样也是轻量级的 Web 框架,类似 Web.py。提供异步非阻塞 IO 的处理方式使其拥有较为出色的抗负载能力。 709 | 710 | == 4.4 Web前端 & JS整合 == 711 | 712 |

Pyjamas & pyjs

713 | 714 | Home:[http://pyjs.org/] 715 | 716 | 这是从 GWT(Google Web Toolkit)移植的第三方库。提供了 Python 到 JS 的编译,AJAX 框架等功能。 717 | 718 | Pyjamas 甚至能用来开发桌面 GUI 应用。 719 | 720 |

pyjaco

721 | 722 | Home:[https://github.com/chrivers/pyjaco] 723 | 724 | 这也是一个 Python 到 JavaScript 的编译工具。 725 | 726 | == 4.5 浏览器整合 == 727 | 728 |

webbrowser

729 | 730 | 【标准库】 731 | 732 | 操纵当前系统的默认浏览器,访问指定 URL 的页面。 733 | 734 | 代码示例——用默认浏览器打开 Google 主页 735 | 736 | import webbrowser 737 | webbrowser.open("http://www.google.com") 738 | 739 | 740 |

pyv8

741 | 742 | Home:[https://pypi.python.org/pypi/PyV8] 743 | 744 | [https://developers.google.com/v8/ v8] 是 Google 开发的 JavaScript 解释引擎。这是对 v8 引擎的 Python 封装。 745 | 746 | 代码示例 747 | 748 | import PyV8 749 | 750 | ctxt1 = PyV8.JSContext() 751 | ctxt1.enter() 752 | ctxt1.eval("1+2") # 对 JS 表达式求值 753 | 754 | class Global(PyV8.JSClass) : # 定义一个兼容 JS 的类 755 | def hello(self) : 756 | print("Hello, world") 757 | 758 | ctxt2 = PyV8.JSContext(Global()) # 创建一个 JS 上下文,传入 Global 类的对象 759 | ctxt2.enter() 760 | ctxt2.eval("hello()") # 调用 hello() 函数 761 | 762 | 763 |

PyWebKitGtk

764 | 765 | Home:[https://github.com/jmalonzo/pywebkitgtk] 766 | 767 | [http://webkitgtk.org/ WebKitGtk] 是一个基于 WebKit 的 Web 渲染引擎。 768 | 769 | PyWebKitGtk 则提供了对 WebKitGtk 的 Python 封装。 770 | 771 | == 4.6 WebSocket == 772 | 773 | (关于 WebSocket 的介绍,可以参见维基百科的“[https://zh.wikipedia.org/wiki/WebSocket 这个链接]”) 774 |

pywebsocket

775 | 776 | Home:[https://github.com/google/pywebsocket] 777 | 778 | 这是 Google 提供的 WebSocket【服务端】。 779 | 780 | 该项目包含一个可独立运行的 server 以及一个 Apache 扩展模块(mod_pywebsocket)。 781 | 782 |

AutobahnPython

783 | 784 | Home:[https://github.com/crossbario/autobahn-python] 785 | 786 | 这是 [http://crossbar.io/autobahn Autobahn] 项目的子项目,同时提供了 WebSocket 的“服务端 & 客户端”。 787 | 788 | 它兼容 Python2 和 Python3,另外还兼容 PyPy 和 Jython。 789 | 790 | 网络方面,它可以跟“asyncio 标准库”以及“[https://en.wikipedia.org/wiki/Twisted_%28software%29 Twisted]”整合。 791 | 792 | 除了实现 WebSocket 协议,它还完整实现了 WAMP(Web Application Messaging Protocol)。 793 | 794 | 代码示例——Echo Server 795 | 796 | from autobahn.twisted.websocket import WebSocketServerProtocol 797 | 798 | class MyServerProtocol(WebSocketServerProtocol) : 799 | def onConnect(self, request) : 800 | print("Client connecting: {}".format(request.peer)) 801 | 802 | def onOpen(self) : 803 | print("WebSocket connection open.") 804 | 805 | def onMessage(self, payload, isBinary) : 806 | if isBinary : 807 | print("Binary message received: {} bytes".format(len(payload))) 808 | else: 809 | print("Text message received: {}".format(payload.decode("utf8"))) 810 | self.sendMessage(payload, isBinary) 811 | 812 | def onClose(self, wasClean, code, reason) : 813 | print("WebSocket connection closed: {}".format(reason)) 814 | 815 | 816 |

ws4py

817 | 818 | Home:[https://github.com/Lawouach/WebSocket-for-Python] 819 | 820 | 此项目同时提供了 WebSocket 的“服务端 & 客户端”;并同时兼容 Python2 和 Python3。 821 | 822 | 其【服务端】可以跟“CherryPy、gevent、wsgiref、asyncio”整合;其【客户端】可以跟“Tornado、gevent”整合。 823 | 824 | == 4.7 (其它) == 825 | 826 |

selenium

827 | 828 | Home:[http://www.seleniumhq.org/] 829 | 830 | selenium 是一个非常优秀的框架,用于爬虫和 Web 自动化测试。 831 | 832 | 代码示例——模拟登录 833 | 834 | from selenium import webdriver 835 | 836 | driver = webdriver.Chrome() 837 | driver.get("http://192.168.1.1") 838 | driver.find_element_by_xpath('//*[@id="lgPwd"]').send_keys("123456") 839 | driver.find_element_by_xpath('//*[@id="loginSub"]').click() 840 | driver.quit() 841 | 842 | 843 |

scrapy

844 | 845 | Home:[https://scrapy.org/] 846 | 847 | Links:[https://en.wikipedia.org/wiki/Scrapy Wikipedia] 848 | 849 | Scrapy 是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 850 | 851 | 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。 852 | 853 | ---- 854 | 855 | = 5 网络 = 856 | 857 | == 5.1 链路层 & 网络层 == 858 | 859 |

Scapy

860 | 861 | Home:[http://www.secdev.org/projects/scapy/] 862 | 863 | Links:[https://en.wikipedia.org/wiki/Scapy Wikipedia] 864 | 865 | 这是一个底层的网络库,可以在不同协议层次构造网络数据包(包括链路层、网络层、传输层),还支持 Sniffer 抓包。 866 | 867 | 搞网络安全的网友应该会喜欢这个库。 868 | 869 | 代码示例 870 | 871 | # 传统的 ping 扫描(网络层) 872 | ans,unans = sr(IP(dst="192.168.1.1-254")/ICMP()) 873 | 874 | # 局域网内的 ARP 扫描(链路层) 875 | ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.1.0/24"), timeout=2) 876 | 877 | 878 | == 5.2 传输层 == 879 | 880 |

socket

881 | 882 | Python 标准库很早就提供了对 socket 编程的支持。 883 | 884 | 这个标准库是对伯克利套接字进行简单的封装,其 API 基本上跟 BSD SOCKET 一一对应。 885 | 886 |

asyncore

887 | 888 | 这个标准库提供了异步 SOCKET 的支持。 889 | 890 |

asynchat

891 | 892 | 这个标准库基于上述的 asyncore,提供更高层的 API,简化异步通讯编程。 893 | 894 | == 5.3 标准的应用层 == 895 | 896 | === 5.3.1 综合性的库 === 897 | 898 |

PycURL

899 | 900 | Home:[http://pycurl.sourceforge.net/] 901 | 902 | [https://en.wikipedia.org/wiki/Curl cURL] 是一个功能很强的网络库/网络工具,支持 N 多应用层协议。俺在前几年写过一篇博文推荐它(在“[https://program-think.blogspot.com/2009/03/opensource-review-curl-library.html 这里]”)。 903 | 904 | 看名称就能猜到——PycURL 是 cURL 的 Python 封装。 905 | 906 | 代码示例——发起 HTTP GET 请求 907 | 908 | import pycurl 909 | try : 910 | from io import BytesIO 911 | except ImportError : 912 | from StringIO import StringIO as BytesIO 913 | 914 | buffer = BytesIO() 915 | curl = pycurl.Curl() 916 | curl.setopt(curl.URL, "http://pycurl.sourceforge.net/") 917 | curl.setopt(curl.WRITEDATA, buffer) 918 | curl.perform() 919 | curl.close() 920 | body = buffer.getvalue() 921 | 922 | 923 | === 5.3.2 HTTP === 924 | 925 | (关于“HTTP 协议”,请参见另一个大类:“Web”) 926 | 927 | === 5.3.3 文件传输 === 928 | 929 |

ftplib

930 | 931 | 【标准库】 932 | 933 | 封装 FTP(File Transfer Protocol)协议 934 | 935 | 代码示例——列出 FTP 服务器上某目录的内容 936 | 937 | from ftplib import FTP 938 | 939 | ftp = FTP("ftp.debian.org") # 连接服务器(如果不指定端口号,则用默认端口号 21) 940 | ftp.login() # 登录(如果不指定用户名和密码,则用匿名登录) 941 | ftp.cwd("debian") # 切换到 "debian" 目录 942 | ftp.retrlines("LIST") # 列出当前目录的内容 943 | ftp.quit() 944 | 945 | 946 |

pysftp

947 | 948 | Home:[https://bitbucket.org/dundeemt/pysftp] 949 | 950 | 封装 [https://en.wikipedia.org/wiki/SSH_File_Transfer_Protocol SFTP] 协议,依赖于 ssh.py 951 | 952 | 代码示例——简单的上传/下载 953 | 954 | import pysftp 955 | 956 | with pysftp.Connection("hostxxx", username="userxxx", password="xxxxxx") as sftp : 957 | with sftp.cd("public") # 服务端当前目录切换到 public 958 | sftp.put("/my/local/filename") # 上传某个本地文件到服务端的 public 目录 959 | sftp.get_r("myfiles", "/local") # 递归复制某个服务端的目录到本地 960 | 961 | 962 | === 5.3.4 电子邮件 === 963 | 964 |

smtplib

965 | 966 | 【标准库】 967 | 968 | 封装 SMTP(Simple Mail Transfer Protocol)协议 969 | 970 |

imaplib

971 | 972 | 【标准库】 973 | 974 | 封装 IMAP(Internet Message Access Protocol)协议 975 | 976 |

poplib

977 | 978 | 【标准库】 979 | 980 | 封装 POP3(Post Office Protocol v3)协议 981 | 982 |

yagmail

983 | 984 | Home:[https://github.com/kootenpv/yagmail] 985 | 986 | 一个非常简单易用的用来发送邮件的第三方库。 987 | 988 | 代码示例 989 | 990 | import yagmail 991 | 992 | yag = yagmail.SMTP("my_gmail_username", "my_gmail_password") 993 | contents = ["This is the body, and here is just text http://somedomain/image.png", 994 | "You can find an audio file attached.', '/local/path/song.mp3"] 995 | yag.send("to@someone.com", "subject", contents) 996 | 997 | 998 | === 5.3.5 即时通讯 === 999 | 1000 |

jabber.py

1001 | 1002 | Home:[http://jabberpy.sourceforge.net/] 1003 | 1004 | Jabber(又称 XMPP)是IM(即时通信)协议的标准。这是用 Python 封装的第三方库。 1005 | 1006 |

irclib

1007 | 1008 | Home:[https://bitbucket.org/jaraco/irc] 1009 | 1010 | IRC 是 Internet Relay Chat 的缩写。这是用 Python 封装的第三方库。 1011 | 1012 |

pyTelegramBotAPI

1013 | 1014 | Home:[https://github.com/eternnoir/pyTelegramBotAPI] 1015 | 1016 | 一个简单、易用的 [https://core.telegram.org/bots TelegramBot] 封装。 1017 | 1018 |

Telethon

1019 | 1020 | Home:[https://github.com/LonamiWebs/Telethon] 1021 | 1022 | 纯 Python3 的 [https://telegram.org/ Telegram] 客户端封装。 1023 | 1024 | === 5.3.6 远程控制 === 1025 | 1026 |

telnetlib

1027 | 1028 | 【标准库】 1029 | 1030 | 封装 telnet 协议 1031 | 1032 | 代码示例——使用 telnet 登录到某个主机并执行简单命令 1033 | 1034 | import telnetlib 1035 | import getpass 1036 | 1037 | host = raw_input("Enter remote host: ") 1038 | user = raw_input("Enter your remote account: ") 1039 | password = getpass.getpass() 1040 | 1041 | tn = telnetlib.Telnet(host) 1042 | 1043 | tn.read_until("login: ") 1044 | tn.write(user + "\n") 1045 | 1046 | if password : 1047 | tn.read_until("Password: ") 1048 | tn.write(password + "\n") 1049 | 1050 | tn.write("ls\n") 1051 | tn.write("exit\n") 1052 | 1053 | print tn.read_all() 1054 | 1055 | 1056 |

rdpy

1057 | 1058 | Home:[https://github.com/citronneur/rdpy] 1059 | 1060 | 纯 Python 实现的 RDP([https://en.wikipedia.org/wiki/Remote_Desktop_Protocol 微软远程桌面协议])和 VNC([https://en.wikipedia.org/wiki/Virtual_Network_Computing Virtual Network Computing])客户端,依赖于 Twisted 库 1061 | 1062 |

paramiko

1063 | 1064 | Home:[http://www.paramiko.org/] 1065 | 1066 | paramiko 是用 python 语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。 1067 | 1068 | 除了 SSH 协议之外,paramiko 还支持SFTP。 1069 | 1070 | 代码示例 1071 | 1072 | import paramiko 1073 | 1074 | ssh = paramiko.SSHClient() 1075 | ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 1076 | ssh.connect("IP", port, "username", "password") 1077 | 1078 | 1079 | === 5.3.7 (其它) === 1080 | 1081 |

urlparse

1082 | 1083 | 【标准库】 1084 | 1085 | 用于解析 URL,提取各个部分的内容。从 Python 2.5 版本开始加入到标准库中,从 Python 2.7 开始支持包含 IPv6 的 URL 1086 | 1087 | == 5.4 自定义的应用层 == 1088 | 1089 |

Protocol Buffers

1090 | 1091 | Home:[https://developers.google.com/protocol-buffers/] 1092 | 1093 | Links:[https://en.wikipedia.org/wiki/Protocol_Buffers Wikipedia] 1094 | 1095 | 这是 Google 开发的一个跨语言的库,用于网络传输业务数据时的“编码/解码”。 1096 | 1097 | 其优点是:跨多种语言、高性能、向前兼容、向后兼容。俺前几年写过一篇博文推荐 protobuf(在“[https://program-think.blogspot.com/2009/05/opensource-review-protocol-buffers.html 这里]”)。 1098 | 1099 | 作为 Protocol Buffers 的发明者,Google 默认实现了三种编程语言(C++、Java、Python)对它的支持。 1100 | 1101 |

Apache Thrift

1102 | 1103 | Home:[https://thrift.apache.org/] 1104 | 1105 | Links:[https://en.wikipedia.org/wiki/Apache_Thrift Wikipedia] 1106 | 1107 | 来自于 Apache 社区,提供了一种跨语言的通讯机制。 1108 | 1109 | 程序员通过 Thrift 的“接口定义语言”定义通讯协议格式,然后 Thrift 根据协议格式自动帮你生成服务端和客户端代码。 1110 | 1111 | (在这个方面,它有点类似于 Google 的 Protocol Buffers) 1112 | 1113 | == 5.5 网络库、框架、中间件 == 1114 | 1115 |

Twisted

1116 | 1117 | Home:[http://twistedmatrix.com/] 1118 | 1119 | Links:[https://en.wikipedia.org/wiki/Twisted_%28software%29 Wikipedia] 1120 | 1121 | 这是一个基于 Python 网络通讯开发框架,诞生于2002年,名气很大。 1122 | 1123 | 它的某些设计类似于 C++ 的 [https://en.wikipedia.org/wiki/Adaptive_Communication_Environment ACE] 框架。除了能用来进行传输层(TCP UDP)的开发,还提供了若干应用层协议(HTTP、XMPP、SSH、IRC ...)的支持。 1124 | 1125 | 代码示例——实现一个简单的 Echo 服务,监听在 12345 端口 1126 | 1127 | from twisted.internet import protocol, reactor 1128 | 1129 | class Echo(protocol.Protocol) : 1130 | def dataReceived(self, data) : 1131 | self.transport.write(data) 1132 | 1133 | class EchoFactory(protocol.Factory) : 1134 | def buildProtocol(self, addr) : 1135 | return Echo() 1136 | 1137 | reactor.listenTCP(12345, EchoFactory()) 1138 | reactor.run() 1139 | 1140 | 1141 |

gevent

1142 | 1143 | Home:[http://www.gevent.org/] 1144 | 1145 | 这是一个基于[https://zh.wikipedia.org/wiki/%E5%8D%8F%E7%A8%8B 协程]的网络库,原先其底层依赖于 libevent,后来改为 libev。 1146 | 1147 | 很多开源项目用到了 gevent,具体参见 [https://github.com/gevent/gevent/wiki/Projects gevent 官方的 wiki]。 1148 | 1149 | 代码示例——并发执行网络请求 1150 | 1151 | from gevent import socket 1152 | import gevent 1153 | 1154 | hosts = ["google.com", "github.com", "program-think.blogspot.com"] 1155 | jobs = [gevent.spawn(socket.gethostbyname, host) for host in hosts] 1156 | gevent.joinall(jobs, timeout=2) 1157 | print([job.value for job in jobs]) 1158 | 1159 | 1160 |

PyZMQ

1161 | 1162 | Home:[https://github.com/zeromq/pyzmq] 1163 | 1164 | 这是 ZMQ(ZeroMQ)的 Python 封装库。同时支持 Python2 和 Python3。 1165 | 1166 | PyZMQ 2.2 之后的版本同时支持 ZMQ 的 3.x 和 4.x 版本。 1167 | 1168 |

nanomsg-python

1169 | 1170 | Home:[https://github.com/tonysimpson/nanomsg-python] 1171 | 1172 | 这是 nanomsg 的 Python 封装库。同时支持 Python2 和 Python3。 1173 | 1174 | 代码示例——Hello world 1175 | 1176 | from __future__ import print_function 1177 | from nanomsg import Socket, PAIR, PUB 1178 | 1179 | s1 = Socket(PAIR) 1180 | s2 = Socket(PAIR) 1181 | s1.bind("inproc://test") 1182 | s2.connect("inproc://test") 1183 | s1.send(b"hello world") 1184 | print(s2.recv()) 1185 | s1.close() 1186 | s2.close() 1187 | 1188 | 1189 | == 5.6 云计算 == 1190 | 1191 |

Apache Libcloud

1192 | 1193 | Home:[https://libcloud.apache.org/] 1194 | 1195 | 如今云提供商越来越多。这个库提供了统一的 API 让你访问各大知名云提供商提供的各种服务。 1196 | 1197 | 代码示例——创建 DNS 记录 1198 | 1199 | from libcloud.dns.types import Provider, RecordType 1200 | from libcloud.dns.providers import get_driver 1201 | 1202 | cls = get_driver(Provider.ZERIGO) 1203 | driver = cls("email", "api key") 1204 | 1205 | zones = driver.list_zones() 1206 | zone = [zone for zone in zones if zone.domain == "mydomain.com"][0] 1207 | 1208 | record = zone.create_record(name="www", type=RecordType.A, data="127.0.0.1") 1209 | print(record) 1210 | 1211 | 1212 | ---- 1213 | 1214 | = 6 数据库 = 1215 | 1216 | 为了便于数据库开发,Python 社区制定了数据库的 API 规范([https://www.python.org/dev/peps/pep-0249/ PEP 249])。 1217 | 1218 | 只要是涉及到数据库操作,标准库和大部分第三方库都会遵循该规范(请看如下几个模块的示例代码)。 1219 | 1220 | == 6.1 数据库中间件 == 1221 | 1222 | === 6.1.1 ODBC === 1223 | 1224 |

pyODBC

1225 | 1226 | Home:[https://github.com/mkleehammer/pyodbc] 1227 | 1228 | pyODBC 封装了 ODBC API,通过它可以访问各种数据库(只要有 ODBC 驱动即可)。 1229 | 1230 | 代码示例——查询某个 ODBC 数据源的某个表 1231 | 1232 | import pyodbc 1233 | 1234 | conn = pyodbc.connect("DSN=xxx;PWD=password") 1235 | cursor = conn.cursor() 1236 | cursor.execute("SELECT field1 FROM table1") 1237 | 1238 | while True : 1239 | row = cursor.fetchone() 1240 | if not row : 1241 | break 1242 | print(row) 1243 | 1244 | cursor.close() 1245 | conn.close() 1246 | 1247 | 1248 |

ceODBC

1249 | 1250 | Home:[http://ceodbc.sourceforge.net/] 1251 | 1252 | 又一个封装 ODBC API 的第三方库 1253 | 1254 | === 6.1.2 JDBC === 1255 | 1256 |

Jython

1257 | 1258 | Jython 前面已经介绍过。有了它,你可以基于 [https://en.wikipedia.org/wiki/Jdbc JDBC] 操作数据库。 1259 | 1260 | === 6.1.3 ADO & ADO.NET === 1261 | 1262 |

PyWin32

1263 | 1264 | PyWin32 前面已经介绍过。有了它,你可以基于 [https://en.wikipedia.org/wiki/ActiveX_Data_Objects ADO] 操作数据库。 1265 | 1266 |

IronPython

1267 | 1268 | IronPython 前面已经介绍过。有了它,你可以基于 [https://en.wikipedia.org/wiki/ADO.NET ADO.NET] 操作数据库。 1269 | 1270 | == 6.2 特定数据库 == 1271 | 1272 | === 6.2.1 MySQL === 1273 | 1274 |

MySQL for Python

1275 | 1276 | Home:[http://mysql-python.sourceforge.net/] 1277 | 1278 | 操作 MySQL 的第三方库。 1279 | 1280 | 代码示例——查询某个 MySQL 数据库的某个表 1281 | 1282 | import MySQLdb 1283 | 1284 | conn = MySQLdb.connect(db="test", passwd="password") 1285 | cursor = conn.cursor() 1286 | cursor.execute("SELECT field1 FROM table1") 1287 | 1288 | while True : 1289 | row = cursor.fetchone() 1290 | if not row : 1291 | break 1292 | print(row) 1293 | 1294 | cursor.close() 1295 | conn.close() 1296 | 1297 | 1298 | === 6.2.2 PostgreSQL === 1299 | 1300 |

psycopg

1301 | 1302 | Home:[http://initd.org/psycopg/] 1303 | 1304 | 操作 PostgreSQL 的第三方库。 1305 | 1306 |

PyGreSQL

1307 | 1308 | Home:[http://www.pygresql.org/] 1309 | 1310 | 操作 PostgreSQL 的第三方库。 1311 | 1312 | === 6.2.3 Oracle === 1313 | 1314 |

cx_Oracle

1315 | 1316 | Home:[http://cx-oracle.sourceforge.net/] 1317 | 1318 | 操作 Oracle 的第三方库。 1319 | 1320 | === 6.2.4 MS SQL Server === 1321 | 1322 |

pymssql

1323 | 1324 | Home:[http://pymssql.org/] 1325 | 1326 | 操作微软 SQL Server 的第三方库。 1327 | 1328 | === 6.2.5 IBM DB2 === 1329 | 1330 |

ibm-db

1331 | 1332 | Home:[https://pypi.python.org/pypi/ibm_db] 1333 | 1334 | 操作 DB2 的第三方库。 1335 | 1336 | === 6.2.6 SQLite === 1337 | 1338 |

sqlite3

1339 | 1340 | 【标准库】 1341 | 1342 | sqlite3 从 Python 2.5 版本开始加入到标准库中。通过它,你可以很方便地操作 SQLite 数据库。 1343 | 1344 | [https://en.wikipedia.org/wiki/SQLite SQLite] 是一个很优秀的轻量级数据库,俺前几年写过一篇博文推荐它(在“[https://program-think.blogspot.com/2009/04/how-to-use-sqlite.html 这里]”)。 1345 | 1346 | 代码示例——创建一个内存数据库,建表并插入记录 1347 | 1348 | import sqlite3 1349 | conn = sqlite3.connect(":memory:") # ":memory:" 表示这是一个内存数据库 1350 | cursor = conn.cursor() 1351 | cursor.execute("CREATE TABLE person (name text, age int)") 1352 | cursor.execute("INSERT INTO stocks VALUES ('TOM',20)") 1353 | conn.commit() 1354 | conn.close() 1355 | 1356 | 1357 | === 6.2.7 MongoDB === 1358 | 1359 |

PyMongo

1360 | 1361 | Docs:[https://docs.mongodb.com/ecosystem/drivers/python/] 1362 | 1363 | 这是 MongoDB 官方提供的 Python 驱动。 1364 | 1365 | === 6.2.8 Apache HBase === 1366 | 1367 |

HappyBase

1368 | 1369 | Home:[https://github.com/wbolster/happybase] 1370 | 1371 | 操作 HBase 的 Python 库,基于 [https://en.wikipedia.org/wiki/Apache_Thrift Thrift] 连接到 HBase。 1372 | 1373 | 代码示例——简单的存取操作 1374 | 1375 | import happybase 1376 | connection = happybase.Connection("hostname") 1377 | table = connection.table("table-name") 1378 | table.put(b"row-key", {b"test1": b"data1", b"test2": b"data2"}) 1379 | row = table.row(b"row-key") 1380 | print(row[b"test1"]) 1381 | 1382 | 1383 | === 6.2.9 Redis === 1384 | 1385 |

redis-py

1386 | 1387 | Home:[https://github.com/andymccurdy/redis-py] 1388 | 1389 | 操作 Redis 的第三方 Python 客户端。 1390 | 1391 | 代码示例——简单的存取操作 1392 | 1393 | import redis 1394 | r = redis.StrictRedis(host="localhost", port=6379, db=0) 1395 | r.set("foo", "bar") 1396 | print(r.get("foo")) 1397 | 1398 | 1399 | === 6.2.10 LevelDB === 1400 | 1401 |

Plyvel

1402 | 1403 | Home:[https://github.com/wbolster/plyvel] 1404 | 1405 | 操作 LevelDB 的 Python 库,速度快,同时兼容 Python2 和 Python3。 1406 | 1407 | 代码示例——简单的存取操作 1408 | 1409 | import plyvel 1410 | db = plyvel.DB("/tmp/testdb/", create_if_missing=True) 1411 | db.put(b"key", b"value") 1412 | print(db.get(b"key")) 1413 | db.close() 1414 | 1415 | 1416 | === 6.2.11 Berkeley DB === 1417 | 1418 |

PyBSDDB

1419 | 1420 | Home:[http://www.jcea.es/programacion/pybsddb.htm] 1421 | 1422 | 操作 Berkeley DB 的第三方库。 1423 | 1424 | == 6.3 ORM(Object-Relational Mapping) == 1425 | 1426 |

SQLAlchemy

1427 | 1428 | Home:[http://www.sqlalchemy.org/] 1429 | 1430 | Links:[https://en.wikipedia.org/wiki/SQLAlchemy Wikipedia] [https://zh.wikipedia.org/wiki/SQLAlchemy 维基百科] 1431 | 1432 | SQLAlchemy 支持的数据库有:MySQL、PostgreSQL、Sqlite、Oracle、MS SQL Server、Firebird、Sybase SQL Server、Informix、等。 1433 | 1434 | 代码示例——通过对象的方式创建两张依赖关系的表 1435 | 1436 | from sqlalchemy import * 1437 | from sqlalchemy.ext.declarative import declarative_base 1438 | from sqlalchemy.orm import relation, sessionmaker 1439 | 1440 | Base = declarative_base() 1441 | 1442 | class Movie(Base) : 1443 | __tablename__ = "movies" 1444 | 1445 | id = Column(Integer, primary_key=True) 1446 | title = Column(String(255), nullable=False) 1447 | year = Column(Integer) 1448 | directed_by = Column(Integer, ForeignKey("directors.id")) 1449 | director = relation("Director", backref="movies", lazy=False) 1450 | 1451 | def __init__(self, title=None, year=None) : 1452 | self.title = title 1453 | self.year = year 1454 | 1455 | def __repr__(self) : 1456 | return "Movie(%r, %r, %r)" % (self.title, self.year, self.director) 1457 | 1458 | class Director(Base) : 1459 | __tablename__ = "directors" 1460 | 1461 | id = Column(Integer, primary_key=True) 1462 | name = Column(String(50), nullable=False, unique=True) 1463 | 1464 | def __init__(self, name=None) : 1465 | self.name = name 1466 | 1467 | def __repr__(self) : 1468 | return "Director(%r)" % (self.name) 1469 | 1470 | Base.metadata.create_all(create_engine("dbms://user:pwd@host/dbname")) 1471 | 1472 | 1473 |

SQLObject

1474 | 1475 | Home:[http://sqlobject.org/] 1476 | 1477 | Links:[https://en.wikipedia.org/wiki/SQLObject Wikipedia] 1478 | 1479 | SQLObject 支持的数据库有:MySQL、PostgreSQL、Sqlite、MS SQL Server、Firebird、Sybase SQL Server、SAP DB、等。 1480 | 1481 | 代码示例——通过对象的方式创建表 1482 | 1483 | from sqlobject import * 1484 | sqlhub.processConnection = connectionForURI("sqlite:/:memory:") 1485 | 1486 | class Person(SQLObject) : 1487 | first_name = StringCol() 1488 | last_name = StringCol() 1489 | 1490 | Person.createTable() 1491 | 1492 | 1493 |

Peewee

1494 | 1495 | Home:[http://www.peewee-orm.com/] 1496 | 1497 | 一个轻量级的 ORM,支持 SQLite、MySQL 和 PostgreSQL,通过插件机制支持更多数据库。 1498 | 1499 | 同时支持 Python2 和 Python3。 1500 | 1501 | 代码示例——通过对象的方式创建表 1502 | 1503 | from peewee import * 1504 | 1505 | db = SqliteDatabase("test.db") 1506 | 1507 | class Person(Model) : 1508 | name = CharField() 1509 | birthday = DateField() 1510 | is_relative = BooleanField() 1511 | class Meta : 1512 | database = db # This model uses the "test.db". 1513 | 1514 | class Pet(Model) : 1515 | owner = ForeignKeyField(Person, related_name="pets") 1516 | name = CharField() 1517 | animal_type = CharField() 1518 | class Meta : 1519 | database = db # This model uses the "test.db". 1520 | 1521 | db.connect() 1522 | db.create_tables([Person, Pet]) 1523 | 1524 | 1525 | ---- 1526 | 1527 | = 7 GUI = 1528 | 1529 | == 7.1 GUI 框架 == 1530 | 1531 | === 7.1.1 基于 Tk === 1532 | 1533 | [https://en.wikipedia.org/wiki/Tk_(framework) Tk] 是一个跨平台的界面组件库。 1534 | 1535 |

Tkinter & tkinter

1536 | 1537 | 【标准库】 1538 | 1539 | 这是 Python 内置的标准库,封装了 Tcl/Tk 界面库。 1540 | 1541 | Python2 的模块名叫 Tkinter,到 Python3 模块名改为 tkinter 1542 | 1543 | 代码示例——用 Tkinter 写 Hello world 1544 | 1545 | from Tkinter import * 1546 | 1547 | if __name__ == "__main__" : 1548 | root = Tk() 1549 | label = Label(root, text="Hello, world") 1550 | label.pack() 1551 | root.mainloop() 1552 | 1553 | 1554 | === 7.1.2 基于 wxWidgets === 1555 | 1556 | [https://en.wikipedia.org/wiki/WxWidgets wxWidgets] 是 C++ 开发的跨平台框架(不仅包括 GUI,还有其它功能)。 1557 |

wxPython

1558 | 1559 | Home:[http://www.wxpython.org/] 1560 | 1561 | Links:[https://en.wikipedia.org/wiki/WxPython Wikipedia] [https://zh.wikipedia.org/wiki/WxPython 维基百科] 1562 | 1563 | 在所有的 wxWidgets 的 Python 封装库中,这个是名气最大的。 1564 | 1565 | [https://github.com/limodou/ulipad Ulipad](知名的国产的 Python IDE)就是基于 wxPython 开发的。 1566 | 1567 | 代码示例——用 wxPython 写 Hello world 1568 | 1569 | import wx 1570 | 1571 | class Frame(wx.Frame) : 1572 | pass 1573 | 1574 | class App(wx.App) : 1575 | def OnInit(self) : 1576 | self.frame = Frame(parent=None, title="Hello, world") 1577 | self.frame.Show() 1578 | self.SetTopWindow(self.frame) 1579 | return True 1580 | 1581 | if __name__ == "__main__" : 1582 | app = App() 1583 | app.MainLoop() 1584 | 1585 | 1586 |

PythonCard

1587 | 1588 | Home:[http://pythoncard.sourceforge.net/] 1589 | 1590 | 又一个基于 wxWidgets 的 GUI 库。 1591 | 1592 | === 7.1.3 基于 GTK+ === 1593 | 1594 | [https://en.wikipedia.org/wiki/GTK%2B GTK+] 全称是(GIMP Toolkit),由 C 开发的跨平台界面组件库。 1595 |

PyGTK

1596 | 1597 | Home:[http://www.pygtk.org/] 1598 | 1599 | Links:[https://en.wikipedia.org/wiki/PyGTK Wikipedia] 1600 | 1601 | 它是 Python 对 GTK+2 的封装。 1602 | 1603 | 代码示例——用 PyGTK 写 Hello world 1604 | 1605 | import pygtk 1606 | pygtk.require("2.0") 1607 | import gtk 1608 | 1609 | class HelloWorld : 1610 | def __init__(self) : 1611 | self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) 1612 | self.window.connect("delete_event", self.delete_event) 1613 | self.window.connect("destroy", self.destroy) 1614 | self.window.set_border_width(10) 1615 | 1616 | self.button = gtk.Button("Hello, world") 1617 | self.button.connect("clicked", self.hello, None) 1618 | self.button.connect_object("clicked", gtk.Widget.destroy, self.window) 1619 | self.window.add(self.button) 1620 | 1621 | self.button.show() 1622 | self.window.show() 1623 | 1624 | def main(self) : 1625 | gtk.main() 1626 | 1627 | def hello(self, widget, data=None) : 1628 | print("Hello, world") 1629 | 1630 | def delete_event(self, widget, event, data=None) : 1631 | print("delete event occurred") 1632 | return False 1633 | 1634 | def destroy(self, widget, data=None) : 1635 | gtk.main_quit() 1636 | 1637 | if __name__ == "__main__" : 1638 | hello = HelloWorld() 1639 | hello.main() 1640 | 1641 | 1642 |

PyGObject(PyGI)

1643 | 1644 | Home:[https://live.gnome.org/PyGObject] 1645 | 1646 | 它是 Python 对 GTK+3 的封装。PyGTK 的官网也推荐它。 1647 | 1648 | 代码示例——用 PyGObject 写 Hello world 1649 | 1650 | from gi.repository import Gtk 1651 | 1652 | class MyWindow(Gtk.Window): 1653 | def __init__(self): 1654 | Gtk.Window.__init__(self, title="Hello World") 1655 | 1656 | self.button = Gtk.Button(label="Click Here") 1657 | self.button.connect("clicked", self.on_button_clicked) 1658 | self.add(self.button) 1659 | 1660 | def on_button_clicked(self, widget): 1661 | print("Hello, world!") 1662 | 1663 | win = MyWindow() 1664 | win.connect("delete-event", Gtk.main_quit) 1665 | win.show_all() 1666 | Gtk.main() 1667 | 1668 | 1669 | === 7.1.4 基于 Qt === 1670 | 1671 | [https://en.wikipedia.org/wiki/Qt_(toolkit) Qt] 是 C++ 开发的跨平台框架(不仅包括 GUI,还有其它功能)。 1672 | 1673 |

PyQt

1674 | 1675 | Home:[http://www.riverbankcomputing.com/software/pyqt/] 1676 | 1677 | Links:[https://en.wikipedia.org/wiki/PyQt Wikipedia] [https://zh.wikipedia.org/wiki/PyQt 维基百科] 1678 | 1679 | 这是 Python 对 Qt 的封装。 1680 | 1681 | 代码示例——用 pyQt 写 Hello world 1682 | 1683 | import sys 1684 | from PyQt4.QtGui import * 1685 | 1686 | if __name__ == "__main__" : 1687 | app = QApplication(sys.argv) 1688 | window = QWidget() 1689 | 1690 | window.resize(320, 240) 1691 | window.setWindowTitle("Hello, world") 1692 | window.show() 1693 | sys.exit(app.exec_()) 1694 | 1695 | 1696 |

PySide

1697 | 1698 | Home:[http://www.pyside.org/] 1699 | 1700 | 这也是 Python 对 Qt 的封装。 1701 | 1702 | === 7.1.5 基于 FLTK === 1703 | 1704 | [https://en.wikipedia.org/wiki/FLTK FLTK] 全称是(Fast Light Tool Kit),由 C++ 开发的跨平台、轻量级界面组件库。 1705 |

PyFLTK

1706 | 1707 | Home:[http://pyfltk.sourceforge.net/] 1708 | 1709 | 这是 Python 对 FLTK 的封装。 1710 | 1711 | === 7.1.6 基于 Windows 平台 === 1712 | 1713 |

PyWin32

1714 | 1715 | PyWin32 前面已经介绍过。它可以提供原生的 Windows GUI 界面。 1716 | 1717 |

IronPython

1718 | 1719 | IronPython 前面已经介绍过。它可以提供 dotNET 的 GUI 界面。 1720 | 1721 | === 7.1.7 基于 JVM 平台 === 1722 | 1723 |

Jython

1724 | 1725 | Jython 前面已经介绍过。它可以提供基于 Java 的 [https://en.wikipedia.org/wiki/Swing_%28Java%29 Swing] 界面。 1726 | 1727 | === 7.1.8 (其它) === 1728 | 1729 |

EasyGUI

1730 | 1731 | Home:[http://easygui.sourceforge.net/] 1732 | 1733 | EasyGUI 这是一个很轻量级的库。跟其它 GUI 不同之处在于——它没有“事件驱动”。 1734 | 1735 |

PyGUI

1736 | 1737 | Home:[http://www.cosc.canterbury.ac.nz/greg.ewing/python_gui/] 1738 | 1739 | PyGUI 是一个更高层的 GUI 库,底层分别封装了 [http://python.net/crew/mhammond/win32/ PyWin32](Windows 平台)、[http://www.pygtk.org/ PyGTK](Linux 平台)、[http://pyobjc.sourceforge.net/ PyObjC](Mac OS X 平台)。 1740 | 1741 |

Kivy

1742 | 1743 | Home:[http://kivy.org/] 1744 | 1745 | 跨平台的多媒体框架和界面库,用来开发比较炫的界面。 1746 | 1747 | 除了支持桌面操作系统,还支持 Android / iOS,支持多点触摸。 1748 | 1749 |

OcempGUI

1750 | 1751 | Home:[http://ocemp.sourceforge.net/gui.html] 1752 | 1753 | 基于 PyGame 的一个跨平台 GUI 库(PyGame 下面会提到)。 1754 | 1755 | == 7.2 图表 & 报表 == 1756 | 1757 |

matplotlib

1758 | 1759 | Home:[http://matplotlib.org/] 1760 | 1761 | Links:[https://en.wikipedia.org/wiki/Matplotlib Wikipedia] 1762 | 1763 | 这是一个有名的图形库,主要用来绘制数学相关的图形。 1764 | 1765 | 它跟后面提到的 [http://www.scipy.org/ SciPy] 整合可以起到类似 MATLAB 的效果。效果图在“[http://matplotlib.org/users/screenshots.html 这里]”。 1766 | 1767 |

Gnuplot.py

1768 | 1769 | Home:[http://gnuplot-py.sourceforge.net/] 1770 | 1771 | 这是 Python 对 [http://www.gnuplot.info/ gnuplot] 的封装。gnuplot 的效果图在“[http://www.gnuplot.info/screenshots/index.html 这里]”。 1772 | 1773 |

PyQtGraph

1774 | 1775 | Home:[http://www.pyqtgraph.org/] 1776 | 1777 | 这是一个纯 Python 的库,依赖于 PyQt4 / PySide。效果图在“[http://www.pyqtgraph.org/images/plotting_sm.png 这里]”。 1778 | 1779 |

PyX

1780 | 1781 | Home:[http://pyx.sourceforge.net/] 1782 | 1783 | 这个库可以跟 TeX / LaTeX 无缝整合,支持导出为 PostScript / PDF 格式。适合用来制作报表。效果图在“[http://pyx.sourceforge.net/gallery/index.html 这里]”。 1784 | 1785 |

Chaco

1786 | 1787 | Home:[http://code.enthought.com/chaco/] 1788 | 1789 | 这是一个商业公司维护的库,主要提供2维图表。效果图在“[http://docs.enthought.com/chaco/user_manual/annotated_examples.html 这里]”。 1790 | 1791 |

Plotly

1792 | 1793 | Home:[https://plot.ly/] 1794 | 1795 | plotly 是现代平台的敏捷商业智能和数据科学库。 1796 | 1797 | 它作为一款开源的绘图库,可以应用于 Python、R、MATLAB、Excel、JavaScript、jupyter 等多种语言。 1798 | 1799 | ---- 1800 | 1801 | = 8 信息安全 = 1802 | 1803 | == 8.1 密码学 == 1804 | 1805 |

hashlib

1806 | 1807 | 【标准库】 1808 | 1809 | 在 Python 2.5 版本加入到标准库中。通过它,你可以很方便地计算各种散列值。 1810 | 1811 | 它支持的哈希算法有:MD5 SHA1 SHA224 SHA256 SHA384 SHA512 1812 | 1813 | 关于散列算法,俺写过一篇扫盲(在“[https://program-think.blogspot.com/2013/02/file-integrity-check.html 这里]”)。 1814 | 1815 | 代码示例——计算字符串的 SHA1 散列值 1816 | 1817 | import hashlib 1818 | sha1 = hashlib.sha1("Hello, world").hexdigest() 1819 | 1820 | 1821 |

PyCrypto

1822 | 1823 | Home:[http://www.dlitz.net/software/pycrypto/] 1824 | 1825 | 这个库包含了常见的对称加密算法(DES、AES、IDEA 等)、公钥加密算法(RSA、DSA 等)、散列算法(MD5、SHA1、RIPEMD 等)。 1826 | 1827 |

pyOpenSSL

1828 | 1829 | Home:[http://pyopenssl.sourceforge.net/] 1830 | 1831 | [https://en.wikipedia.org/wiki/OpenSSL OpenSSL] 在加密领域可是大名鼎鼎。这个库使用 Python 对 OpenSSL 进行很薄的封装。 1832 | 1833 |

Keyczar

1834 | 1835 | Home:[https://github.com/google/keyczar] 1836 | 1837 | 这是 Google 提供的加密库,同时提供 C++、Java、Python 三种语言的实现。 1838 | 1839 | 它提供了比较高层的 API, 使用者无需关心太多的细节。 1840 | 1841 |

passlib

1842 | 1843 | Home:[https://bitbucket.org/ecollins/passlib/] 1844 | 1845 | passlib 是一个久经考验的非常成熟的跨平台的散列函数库,它所提供的功能包括随机盐密码的生成与验证,两步验证等。 1846 | 1847 | 代码示例——验证随机盐密码 1848 | 1849 | >>> # import the hash algorithm 1850 | >>> from passlib.hash import pbkdf2_sha256 1851 | 1852 | >>> # generate new salt, and hash a password 1853 | >>> hash = pbkdf2_sha256.hash("toomanysecrets") 1854 | >>> hash 1855 | '$pbkdf2-sha256$29000$N2YMIWQsBWBMae09x1jrPQ$1t8iyB2A.WF/Z5JZv.lfCIhXXN33N23OSgQYThBYRfk' 1856 | 1857 | >>> # verifying the password 1858 | >>> pbkdf2_sha256.verify("toomanysecrets", hash) 1859 | True 1860 | >>> pbkdf2_sha256.verify("joshua", hash) 1861 | False 1862 | 1863 | 1864 | == 8.2 访问控制 == 1865 | 1866 |

oauth2client

1867 | 1868 | Home:[https://github.com/google/oauth2client] 1869 | 1870 | 这是 Google 提供的 OAuth 客户端,支持 OAuth 2.0 规范。 1871 | 1872 | ---- 1873 | 1874 | = 9 处理文件格式 = 1875 | 1876 | == 9.1 结构化数据格式 == 1877 | 1878 | === 9.1.1 CSV === 1879 | 1880 | [https://en.wikipedia.org/wiki/Comma-separated_values CSV] 是一种历史悠久的结构化数据存储格式。其效果类似于一张数据库二维表。 1881 |

csv

1882 | 1883 | 【标准库】 1884 | 1885 | 提供 CSV 格式文件的读写,可以手动指定行列分隔符。 1886 | 1887 | === 9.1.2 JSON === 1888 | 1889 | JSON 格式源自 JavaScript,如今在 Web 开发中广为应用。 1890 |

json

1891 | 1892 | 【标准库】 1893 | 1894 | 提供 JSON 格式的编码和解码。 1895 | 1896 | 代码示例——编码/解码 JSON 字符串 1897 | 1898 | import json 1899 | 1900 | json.dumps(["foo", {"bar": ("baz", None, 1.0, 2)}]) 1901 | # JSON 编码 1902 | # 得到如下【字符串】 1903 | # """["foo", {"bar": ["baz", null, 1.0, 2]}]""" 1904 | 1905 | json.loads("""["foo", {"bar":["baz", null, 1.0, 2]}]""") 1906 | # JSON 解码 1907 | # 得到如下【对象】 1908 | # [u"foo", {u"bar": [u"baz", None, 1.0, 2]}] 1909 | 1910 | 1911 | === 9.1.3 YAML === 1912 | 1913 | [https://en.wikipedia.org/wiki/YAML YAML] 是一种类似于 json 的结构化数据格式。它在确保可读性的基础上,提供了超越 json 的灵活性和扩展性。 1914 |

PyYAML

1915 | 1916 | Home:[http://pyyaml.org/] 1917 | 1918 | pyyaml 提供了 Python 对 YAML 的封装。 1919 | 1920 | == 9.2 压缩文件 & 打包文件 == 1921 | 1922 | === 9.2.1 zip === 1923 | 1924 |

zipfile

1925 | 1926 | 【标准库】 1927 | 1928 | 提供对 zip 格式的读写。 1929 | 1930 | === 9.2.2 bzip2(bz2) === 1931 | 1932 |

bz2

1933 | 1934 | 【标准库】 1935 | 1936 | 提供对 bzip2 格式的读写。 1937 | 1938 | === 9.2.3 gzip(gz) === 1939 | 1940 |

gzip

1941 | 1942 | 【标准库】 1943 | 1944 | 提供对 gzip 格式的读写。 1945 | 1946 |

zlib

1947 | 1948 | 【标准库】 1949 | 1950 | 提供对 zlib 格式的读写。 1951 | 1952 | === 9.2.4 tar === 1953 | 1954 |

tarfile

1955 | 1956 | 【标准库】 1957 | 1958 | 提供对 tar 格式的读写。 1959 | 1960 | === 9.2.5 7zip(7z) === 1961 | 1962 |

PyLZMA

1963 | 1964 | Home:[http://www.joachim-bauch.de/projects/pylzma/] 1965 | 1966 | 处理 7zip 格式的第三方库。 1967 | 1968 | === 9.2.6 rar === 1969 | 1970 |

rarfile

1971 | 1972 | Home:[http://rarfile.berlios.de/] 1973 | 1974 | 处理 rar 格式的第三方库。 1975 | 1976 | === 9.2.7 msi === 1977 | 1978 |

msilib

1979 | 1980 | 【标准库】 1981 | 1982 | 提供对 msi 格式的读写,从 Python 2.5 版本开始加入标准库。 1983 | 1984 | == 9.3 标记语言 == 1985 | 1986 | === 9.3.1 XML === 1987 | 1988 |

xml.dom & xml.miniDom & xml.etree.ElementTree

1989 | 1990 | 【标准库】 1991 | 1992 | 用 DOM(Document Object Model)方式处理 XML 文件。 1993 | 1994 |

xml.sax & xml.parsers.expat

1995 | 1996 | 【标准库】 1997 | 1998 | 用 SAX(Simple API for XML)方式处理 XML 文件。 1999 | 2000 |

lxml

2001 | 2002 | Home:[http://lxml.de/] 2003 | 2004 | 著名的 C 语言库 libxml 和 libxslt 的 Python 封装。 2005 | 2006 | 功能很强,支持 XPath 1.0、XSLT 1.0、扩展 EXSLT、等。还可以用来解析 HTML 格式。 2007 | 2008 | === 9.3.2 HTML === 2009 | 2010 |

HTMLParser

2011 | 2012 | 【标准库】 2013 | 2014 | 以回调方式解析 HTML/XHTML 文件内容。 2015 | 2016 |

beautifulsoup

2017 | 2018 | Home:[https://www.crummy.com/software/BeautifulSoup/] 2019 | 2020 | Links:[https://zh.wikipedia.org/zh-cn/Beautiful_Soup 维基百科] 2021 | 2022 | Beautiful Soup 可以从 HTML 或 XML 文件中提取数据。 2023 | 2024 | 它是写”爬虫“的利器,通常与 requests 或 selenium 配合。 2025 | 2026 | == 9.4 PDF == 2027 | 2028 |

pyfpdf

2029 | 2030 | Home:[https://github.com/reingart/pyfpdf] 2031 | 2032 | 这是 [http://www.fpdf.org/ FPDF] 的 Python 移植库,用来生成 PDF 文档。 2033 | 2034 | 支持的功能比较全(嵌入字体、嵌入图片),文档也比较详细。 2035 | 2036 | 代码示例——简单的 Hello World 示例 2037 | 2038 | from fpdf import FPDF 2039 | 2040 | pdf = FPDF() 2041 | pdf.add_page() 2042 | pdf.set_font("Arial", "B", 16) 2043 | pdf.cell(40, 10, "Hello, World") 2044 | pdf.output("test.pdf", "F") 2045 | 2046 | 2047 | 代码示例——支持写入 HTML 语法(目前支持几种常见的 HTML tag) 2048 | 2049 | from pyfpdf import FPDF, HTMLMixin 2050 | 2051 | class MyFPDF(FPDF, HTMLMixin) : 2052 | pass 2053 | 2054 | pdf = MyFPDF() 2055 | pdf.add_page() 2056 | pdf.write_html(html) 2057 | pdf.output("test.pdf", "F") 2058 | 2059 | 2060 |

pyPdf & PyPDF2

2061 | 2062 | Home:[http://knowah.github.com/PyPDF2/] 2063 | 2064 | pyPdf 目前已经不继续升级维护了。PyPDF2 是从 pyPdf 派生出来的,并继续增加新功能。 2065 | 2066 | 它除了可以提取文件属性,还可以切分/合并文档,加密/解密文档。 2067 | 2068 |

PDFMiner

2069 | 2070 | Home:[http://www.unixuser.org/~euske/python/pdfminer/] 2071 | 2072 | 它可以提取 PDF 文件属性以及每页的文本,支持把内容输出为 HTML 格式。 2073 | 2074 | == 9.5 MS Office 文档 == 2075 | 2076 | === 9.5.1 Word(doc、docx) === 2077 | 2078 |

python-docx

2079 | 2080 | Home:[https://github.com/python-openxml/python-docx] 2081 | 2082 | 纯 python 实现的 docx 操作库,能够处理 docx 中的“文本、图片、样式”。 2083 | 2084 | 同时支持 Python2 和 Python3。 2085 | 2086 |

PyWin32

2087 | 2088 | PyWin32 前面已经介绍过。它可以基于 [https://en.wikipedia.org/wiki/Component_Object_Model COM] 操作 Office 文档,包括 Word。 2089 | 2090 | (本地需要安装 Office) 2091 | 2092 | === 9.5.2 Excel(xls、xlsx) === 2093 | 2094 |

pyExcelerator

2095 | 2096 | Home:[http://sourceforge.net/projects/pyexcelerator/] 2097 | 2098 | 它可以支持 Office Excel(97/2000/XP/2003)以及 OpenOffice Calc 的文档。无需依赖外部软件。 2099 | 2100 |

PyWin32

2101 | 2102 | PyWin32 前面已经介绍过。它可以基于 [https://en.wikipedia.org/wiki/Component_Object_Model COM] 操作 Office 文档,包括 Excel。 2103 | 2104 | (本地需要安装 Office) 2105 | 2106 | === 9.5.3 Power Point(ppt、pptx) === 2107 | 2108 |

python-pptx

2109 | 2110 | Home:[https://github.com/scanny/python-pptx] 2111 | 2112 | 它可以用来生成 pptx(Open XML PowerPoint)格式的文档。 2113 | 2114 |

PyWin32

2115 | 2116 | PyWin32 前面已经介绍过。它可以基于 [https://en.wikipedia.org/wiki/Component_Object_Model COM] 操作 Office 文档,包括 Power Point。 2117 | 2118 | (本地需要安装 Office) 2119 | 2120 | == 9.6 RTF == 2121 | 2122 |

PyRTF

2123 | 2124 | Home:[http://pyrtf.sourceforge.net/] 2125 | 2126 | 它可以用来处理 RTF(富文本格式)文档。 2127 | 2128 | == 9.7 CHM == 2129 | 2130 |

PyCHM

2131 | 2132 | Home:[http://gnochm.sourceforge.net/pychm.html] 2133 | 2134 | 这是基于 [http://www.jedrea.com/chmlib/ chmlib] 的 Python 封装库。可以提取 CHM 文件的属性以及每个页面的内容。 2135 | 2136 | ---- 2137 | 2138 | = 10 图像 = 2139 | 2140 | == 10.1 图像处理 == 2141 | 2142 |

Python Imaging Library(PIL)

2143 | 2144 | Home:[http://www.pythonware.com/products/pil/] 2145 | 2146 | Links:[https://en.wikipedia.org/wiki/Python_Imaging_Library Wikipedia] 2147 | 2148 | 这是一个很有名气的 Python 图像处理库,支持常见图像文件格式(BMP、JPG、GIF、PNG ...)。 2149 | 2150 | 它可以对图像进行各种常见的处理(旋转、缩放、剪切 ...)。 2151 | 2152 | 代码示例——为某个目录下所有 JPEG 创建缩略图 2153 | 2154 | import os, glob 2155 | from PIL import Image 2156 | 2157 | size = 128, 128 2158 | for file in glob.glob("*.jpg"): 2159 | name, ext = os.path.splitext(file) 2160 | img = Image.open(file) 2161 | img.thumbnail(size) 2162 | img.save(name+".thumbnail", "JPEG") 2163 | 2164 | 2165 | 代码示例——旋转某图片并显示 2166 | 2167 | from PIL import Image 2168 | 2169 | img = Image.open("xxx.jpg") 2170 | img = img.rotate(90) 2171 | img.show() 2172 | 2173 | 2174 |

Wand

2175 | 2176 | Home:[http://docs.wand-py.org/] 2177 | 2178 | 它通过前面提到 ctypes 实现了对 [https://en.wikipedia.org/wiki/ImageMagick ImageMagick] 的封装(ImageMagick 是最强大的开源图片处理工具集)。 2179 | 2180 | 代码示例——旋转并缩放某图片 2181 | 2182 | from wand.image import Image 2183 | from wand.display import display 2184 | 2185 | with Image(filename="mona-lisa.png") as img : 2186 | print(img.size) 2187 | for r in 1, 2, 3 : 2188 | with img.clone() as new_img : 2189 | new_img.resize(int(new_img.width/2), int(new_img.height/2)) 2190 | new_img.rotate(90 * r) 2191 | new_img.save(filename="mona-lisa-{0}.png".format(r)) 2192 | display(new_img) 2193 | 2194 | 2195 |

Pillow

2196 | 2197 | Home:[http://python-pillow.org/] 2198 | 2199 | 你可以把它视作“轻量级的 PIL”。 2200 | 2201 | 它的目标是比 PIL 更容易使用,并尽可能与 PIL 的 API 兼容。 2202 | 2203 |

PyGraphviz

2204 | 2205 | Home:[https://github.com/pygraphviz/pygraphviz] 2206 | 2207 | [https://en.wikipedia.org/wiki/Graphviz Graphviz] 是一个功能很强大的关系图【自动】生成工具,具体介绍可以参见俺的博文(在“[https://program-think.blogspot.com/2016/02/opensource-review-graphviz.html 这里]”) 2208 | 2209 | 这个库如其名所示,提供了 Python 对 Graphviz 的封装(基于 SWIG)。 2210 | 2211 |

Graphviz

2212 | 2213 | Home:[https://github.com/xflr6/graphviz] 2214 | 2215 | 这个库与上一个类似,也提供了 Graphviz 的 Python 的封装。 2216 | 2217 | 这两个库都在 GitHub 上。(可能是因为出现较晚)这个库的 Star 和 Fork 数都不如上一个,不过俺感觉文档比较全。 2218 | 2219 | 代码示例——创建一个 DOT 图并加入若干节点和连线 2220 | 2221 | from graphviz import Digraph 2222 | 2223 | dot = Digraph(comment='The Round Table') 2224 | # 添加节点 2225 | dot.node('A', 'King Arthur') 2226 | dot.node('B', 'Sir Bedevere the Wise') 2227 | dot.node('L', 'Sir Lancelot the Brave') 2228 | # 添加连线 2229 | dot.edges(['AB', 'AL']) 2230 | dot.edge('B', 'L', constraint='false') 2231 | 2232 | 2233 | == 10.2 图像格式转换 == 2234 | 2235 |

Python Imaging Library(PIL)

2236 | 2237 | PIL 前面已经介绍过。它支持常见图像文件格式(BMP、JPG、GIF、PNG ...)之间的相互转换。 2238 | 2239 |

Wand

2240 | 2241 | Wand 前面已经介绍过。由于它是针对 [https://en.wikipedia.org/wiki/ImageMagick ImageMagick] 的封装。只要 ImageMagick 能转换的格式,它也可以转换。 2242 | 2243 | == 10.3 图像渲染 == 2244 | 2245 |

Pycairo

2246 | 2247 | Home:[http://cairographics.org/pycairo/] 2248 | 2249 | [https://en.wikipedia.org/wiki/Cairo_%28graphics%29 Cairo] 是一个图像渲染引擎,提供了矢量图像的渲染功能。支持多种后端输出(包括:Win32 GDI、OpenGL、Xlib、XCB、PDF、PNG、SVG......)。 2250 | 2251 | Pycairo 是 Cairo 官方提供 Python 封装。 2252 | 2253 | = 11 游戏 = 2254 | 2255 | == 11.1 综合性的游戏引擎 == 2256 | 2257 |

PyGame

2258 | 2259 | Home:[http://www.pygame.org/] 2260 | 2261 | Links:[https://en.wikipedia.org/wiki/Pygame Wikipedia] [https://zh.wikipedia.org/wiki/Pygame 维基百科] 2262 | 2263 | 这是名气很大的跨平台游戏引擎,构建于 [https://zh.wikipedia.org/wiki/SDL SDL](Simple DirectMedia Layer)之上。 2264 | 2265 | 它起先是用来替代终止开发的 pySDL,包含了图像和音频的库。 2266 | 2267 |

Cocos2d

2268 | 2269 | Home:[http://cocos2d.org/] 2270 | 2271 | 它是一个开源的 2D 游戏框架,最初使用 Python 编写的。后来该框架已经被移植到了多种语言和平台上。 2272 | 2273 | 其功能包括了:GUI 组件、音效、物理引擎、脚本语言绑定、场景编辑器 ... 2274 | 2275 | 很多手机游戏是基于 Cocos2d 的衍生框架开发的。 2276 | 2277 |

Blender Game Engine

2278 | 2279 | Home:[http://www.blender.org/] 2280 | 2281 | Links:[https://en.wikipedia.org/wiki/Game_Blender Wikipedia] [https://zh.wikipedia.org/wiki/Game_Blender 维基百科] 2282 | 2283 | 它是 [https://en.wikipedia.org/wiki/Blender_%28software%29 Blender] 的组成部分,虽然是以 C++ 编写,但内置了 Python 脚本的扩展。 2284 | 2285 | 其功能包括:3D 渲染、碰撞检测、角色编辑器、音效、网络通讯、AI ... 2286 | 2287 | == 11.2 3D 渲染引擎 == 2288 | 2289 |

PyOpenGL

2290 | 2291 | Home:[http://pyopengl.sourceforge.net/] 2292 | 2293 | 封装 [https://en.wikipedia.org/wiki/OpenGL OpenGL] 的 Python 库。 2294 | 2295 |

Python-Ogre

2296 | 2297 | Home:[http://www.python-ogre.org/] 2298 | 2299 | 封装 [https://en.wikipedia.org/wiki/OGRE OGRE] 的 Python 库。 2300 | 2301 | ---- 2302 | 2303 | = 12 数值计算 & 科学计算 = 2304 | 2305 |

NumPy

2306 | 2307 | Home:[http://www.numpy.org/] 2308 | 2309 | Links:[https://en.wikipedia.org/wiki/NumPy Wikipedia] [https://zh.wikipedia.org/wiki/NumPy 维基百科] 2310 | 2311 | 它提供了功能强大、性能很高的数值数组,可以用来进行各种数值计算(包括矩阵运算)。 2312 | 2313 | 代码示例 2314 | 2315 | # 以下是传统 Python 写法,冗长且速度较慢 2316 | a = range(10000000) 2317 | b = range(10000000) 2318 | c = [] 2319 | for i in range(len(a)) : 2320 | c.append(a[i] + b[i]) 2321 | 2322 | # 以下是 NumPy 的写法,简洁且速度飞快 2323 | import numpy as np 2324 | a = np.arange(10000000) 2325 | b = np.arange(10000000) 2326 | c = a + b 2327 | 2328 | 2329 |

SciPy

2330 | 2331 | Home:[http://www.scipy.org/] 2332 | 2333 | Links:[https://en.wikipedia.org/wiki/SciPy Wikipedia] [https://zh.wikipedia.org/wiki/SciPy 维基百科] 2334 | 2335 | 它依赖 NumPy 提供的多维数组。相比 NumPy,它提供了更高层的数学运算模块(统计、线性代数、积分、常微分方程求解、傅立叶变换、信号处理 ...)。 2336 | 2337 | 它被广泛用于科研和工程领域。 2338 | 2339 |

SymPy

2340 | 2341 | Home:[http://sympy.org/] 2342 | 2343 | Links:[https://en.wikipedia.org/wiki/SymPy Wikipedia] [https://zh.wikipedia.org/wiki/SymPy 维基百科] 2344 | 2345 | 它是用来做符号计算的,其目标是成为一个全功能的“计算机代数系统”。 2346 | 2347 | 它支持的功能包括:符号计算、高精度计算、模式匹配、绘图、解方程、微积分、组合数学、离散数学、几何学、概率与统计 ...... 2348 | 2349 | ---- 2350 | 2351 | = 13 (其它) = 2352 | 2353 | 一些不方便归类的,暂时放到这里。 2354 | 2355 |

PyPy

2356 | 2357 | Home:[http://www.pypy.org/] 2358 | 2359 | Links:[https://en.wikipedia.org/wiki/PyPy Wikipedia] [https://zh.wikipedia.org/wiki/PyPy 维基百科] 2360 | 2361 | 它是一个用 Python 写的 Python 解释器(有点绕口令)。 2362 | 2363 | PyPy 支持 JIT(Just-in-time compilation)和沙箱技术,可做到【比 CPython 更快的运行速度】。 2364 | 2365 | --------------------------------------------------------------------------------