= 4 调试 & 测试 =
== 4.1 调试日志 ==
Boost.Log
Docs:[http://boost.org/libs/log]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了记录日志的机制。
下面给出的示例是最简单的版本,其实它还提供了很丰富的扩展机制。
代码示例
BOOST_LOG_TRIVIAL(debug) << "A debug severity message";BOOST_LOG_TRIVIAL(info) << "An informational severity message";
POCO.Logging
Docs:[http://pocoproject.org/docs/package-Foundation.Logging.html]
POCO 前面已经介绍过。它提供了好几个用于调试日志的封装类(包括特定于 Windows 平台和特定于 POSIX 平台的类)。
它还支持日志文件的循环存储。
Dlib
Docs:[http://dlib.net/other.html#logger]
Dlib 前面已经介绍过。它提供了风格类似 log4j 的日志记录机制。
代码示例
wxWidgets
Docs:[http://docs.wxwidgets.org/trunk/group__group__funcmacro__log.html]
wxWidgets 前面已经介绍过。它提供了记录日志的函数和宏。
log4cpp
Home:[http://log4cpp.sourceforge.net/]
如其名,这是一个模仿 log4j 的 C++ 库。支持多种操作系统(包括 Windows)。
== 4.2 单元测试 ==
Boost.Test
Docs:[http://boost.org/libs/test]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了与测试相关的各种辅助工具(包括单元测试)。
Google Test
Home:[https://github.com/google/googletest]
Links:[https://en.wikipedia.org/wiki/Google_Test Wikipedia]
这是 Google 提供的单元测试框架。从 Google Code 迁移到 GitHub 之后,又整合了 GoogleMock 项目。
一些知名的开源项目(Chromium、LLVM、OpenCV)用到了它。
CppUnit
Home:[http://freedesktop.org/wiki/Software/cppunit/]
Links:[https://en.wikipedia.org/wiki/CppUnit Wikipedia]
如其名,这是一个 C++ 的单元测试框架。该项目起先是作为 JUnit 的 C++ 移植而创建的。
Check
Home:[http://check.sourceforge.net/]
Links:[https://en.wikipedia.org/wiki/Check_%28unit_testing_framework%29 Wikipedia]
这是针对 C 的单元测试框架。
代码示例
/* The basic unit test looks as follows: */
START_TEST (test_name)
{
/* unit test code */
}
END_TEST
/* The “START_TEST/END_TEST” pair are macros that setup basic structures to permit testing.
It is a mistake to leave off the END_TEST marker;
doing so produces all sorts of strange errors when the check is compiled. */
== 4.3 健壮性测试 ==
Boost.Test.ExecutionMonitor
Docs:[http://boost.org/libs/test/doc/html/execution-monitor.html]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,它除了提供“单元测试”,还提供“内存泄漏的检测”。
== 4.4 性能测试 ==
benchmark
Home:[https://github.com/google/benchmark]
这是 Google 提供的性能测试辅助工具,用来测试指定函数的执行时间。
它可以把测试结果导出为 CSV 或 JSON 格式。
—-
= 5 操作系统 =
== 5.1 跨操作系统 ==
=== 5.1.1 文件系统 ===
Boost.Filesystem
Docs:[http://boost.org/libs/filesystem]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了对“文件系统”的操作。
代码示例——获取文件大小
int main(int argc, char* argv[])
{
using namespace boost::filesystem;
if(argc != 2)
{
std::cout << "Usage: \n" << argv[0] << " path\n"; return 1; } std::cout << argv[1] << " " << file_size(argv[1]) << '\n'; return 0;}
POCO.Filesystem
Docs:[http://pocoproject.org/docs/package-Foundation.Filesystem.html]
POCO 前面已经介绍过。它提供了文件系统相关的封装类(遍历目录和文件、通配符匹配、临时文件、文件变化通知…)。
wxWidgets
Docs:[http://docs.wxwidgets.org/trunk/group__group__class__file.html]
wxWidgets 前面已经介绍过。它提供了文件系统相关的封装类(遍历目录和文件、临时文件、文件变化通知…)。
APR
Docs:[https://apr.apache.org/docs/apr/trunk/modules.html]
APR 前面已经介绍过。它提供了“文件信息、文件名匹配”等功能。
=== 5.1.2 线程 ===
Boost.Thread
Docs:[http://boost.org/libs/thread]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“多线程”的功能。
代码示例
void hello_world()
{
std::cout << "Hello world, I'm a thread!\n";}int main(){ boost::thread my_thread(&hello_world); // 启动一个线程 my_thread.join(); // 等待该线程结束 return 0;}
ACE
Docs:[http://www.dre.vanderbilt.edu/Doxygen/Stable/libace-doc/annotated.html]
ACE 前面已经介绍过。它提供了“多线程”的功能(参见文档中以“ACE_Thread”开头的类)
APR
Docs:[https://apr.apache.org/docs/apr/trunk/modules.html]
APR 前面已经介绍过。它提供了“线程池、线程同步/互斥”等功能,以及一些线程安全的数据结构。
POCO.Threading
Docs:[http://pocoproject.org/docs/package-Foundation.Threading.html]
POCO 前面已经介绍过。它提供了线程、线程池以及线程同步/互斥的封装类。
wxWidgets
Docs:[http://docs.wxwidgets.org/trunk/group__group__class__threading.html]
wxWidgets 前面已经介绍过。它提供了线程以及线程同步/互斥的封装类。
GNU Common C++
Home:[http://www.gnu.org/software/commoncpp/]
由 GNU 提供的一套跨平台的线程并发框架。
=== 5.1.3 进程 ===
ACE
Docs:[http://www.dre.vanderbilt.edu/Doxygen/Stable/libace-doc/annotated.html]
ACE 前面已经介绍过。它提供了“进程管理”的功能(参见文档中以“ACE_Process”开头的类)。
APR
Docs:[https://apr.apache.org/docs/apr/trunk/modules.html]
APR 前面已经介绍过。它提供了“进程管理”的功能。
POCO.Processes
Docs:[http://pocoproject.org/docs/Poco.Process.html]
POCO 前面已经介绍过。它提供了“进程”的封装类。
=== 5.1.4 本地进程间通信(IPC) ===
(本章节列举的是【本地】IPC,跨主机的网络通讯,参见本页面后续的章节)
Boost.Interprocess
Docs:[http://boost.org/libs/interprocess]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了共享内存和几种同步机制(Mutexes、Condition variables、Semaphores、Upgradable mutexes、File locks)。
ACE
Docs:[http://www.dre.vanderbilt.edu/Doxygen/Stable/libace-doc/annotated.html]
ACE 前面已经介绍过。它提供了许多种 IPC 机制(有些不是跨平台的)。
APR
Docs:[https://apr.apache.org/docs/apr/trunk/modules.html]
APR 前面已经介绍过。它提供了“进程同步、共享内存、信号处理”等功能。
POCO.Processes
Docs:[http://pocoproject.org/docs/package-Foundation.Processes.html]
POCO 前面已经介绍过。它提供了 IPC 相关的封装类(“共享内存”和“管道”)。
== 5.2 特定于 Windows 系统 ==
=== 5.2.1 注册表 ===
wxWidgets
Docs:[http://docs.wxwidgets.org/trunk/classwx_reg_key.html]
wxWidgets 前面已经介绍过。它提供了操作 Windows 注册表的封装类。
POCO::Util
Docs:[http://pocoproject.org/docs/Poco.Util.html]
POCO 前面已经介绍过。它提供了操作 Windows 注册表的封装类(WinRegistryKey)。
=== 5.2.2 Windows 服务(Service) ===
POCO::Util
Docs:[http://pocoproject.org/docs/Poco.Util.html]
POCO 前面已经介绍过。它提供了相应的封装类(WinService),可以用来操作 Service(注册、删除、启动、停止)。
== 5.3 特定于 Linux & Unix 系统 ==
—-
= 6 图形用户界面(GUI) =
== 6.1 GUI 框架 ==
=== 6.1.1 跨平台的 GUI 框架 ===
wxWidgets
Docs:[http://docs.wxwidgets.org/trunk/modules.html]
wxWidgets 前面已经介绍过。用 wxWidgets 开发 GUI 应用,其代码结构类似 MFC。熟悉 MFC 的程序员应该很容易上手。
代码示例——Hello world
class MyApp: public wxApp
{
public:
virtual bool OnInit();
};
wxIMPLEMENT_APP(MyApp);
class MyFrame: public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
private:
void OnExit(wxCommandEvent& event);
wxDECLARE_EVENT_TABLE();
};
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
wxEND_EVENT_TABLE()
bool MyApp::OnInit()
{
MyFrame* frame = new MyFrame(“Hello, World”, wxPoint(50, 50), wxSize(450, 340));
frame->Show(true);
return true;
}
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame(NULL, wxID_ANY, title, pos, size)
{
wxMenu* menuFile = new wxMenu();
menuFile->Append(wxID_EXIT);
wxMenuBar* menuBar = new wxMenuBar();
menuBar->Append(menuFile, “&File”);
SetMenuBar(menuBar);
}
void MyFrame::OnExit(wxCommandEvent& event)
{
Close(true);
}
Qt
Qt 前面已经介绍过。下面给出一个 Hello world 的示例,让你看看 Qt 的风格。
代码示例——Hello world
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QLabel label(“Hello, world!”);
label.show();
return app.exec();
}
GTK+
Home:[http://www.gtk.org/]
Links:[https://en.wikipedia.org/wiki/GTK%2B Wikipedia] [https://zh.wikipedia.org/wiki/GTK%2B 维基百科]
老牌的 GUI 框架,诞生于1998年。原先叫做“GIMP Toolkit”,是基于 C 开发的跨平台界面组件库。
代码示例——Hello world
int main(int argc, char* argv[])
{
gtk_init(&argc, &argv);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), “Hello, world!”);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 200, 100);
/*
** Map the destroy signal of the window to gtk_main_quit;
** When the window is about to be destroyed, we get a notification and
** stop the main GTK+ loop by returning 0
*/
g_signal_connect(window, “destroy”, G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
/* Start the main loop, do nothing until the application is closed */
gtk_main();
return 0;
}
FLTK
Home:[http://www.fltk.org/]
Links:[https://en.wikipedia.org/wiki/FLTK Wikipedia] [https://zh.wikipedia.org/wiki/FLTK 维基百科]
它的全称是“Fast, Light Toolkit”。如其名,它非常轻量级。用它写一个“Hello World 应用”,静态链接后大约才 100KB
代码示例——Hello world
int main(int argc, char **argv)
{
Fl_Window* window = new Fl_Window(300, 180);
Fl_Box* box = new Fl_Box(20, 40, 260, 100, “Hello, World!”);
box->box(FL_UP_BOX);
box->labelsize(36);
box->labelfont(FL_BOLD+FL_ITALIC);
box->labeltype(FL_SHADOW_LABEL);
window->end();
window->show(argc, argv);
return Fl::run();
}
=== 6.1.2 特定于 Windows 的 GUI 框架 ===
WTL(Windows Template Library)
Home:[http://sourceforge.net/projects/wtl/]
Links:[https://en.wikipedia.org/wiki/Windows_Template_Library Wikipedia] [https://zh.wikipedia.org/wiki/Windows_Template_Library 维基百科]
这是微软雇员 Nenad Stefanovic 开发的开源 GUI 框架。开发 WTL 是为了提供一个轻量级的 MFC 替代品。
== 6.2 图表(Chart) ==
Qt
Docs:[http://doc.qt.io/QtCharts/]
Qt 前面已经介绍过。它内置了一套 Chart 的封装类。
代码示例——饼图
QT_CHARTS_USE_NAMESPACE
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QPieSeries* series = new QPieSeries();
series->append(“Jane”, 1);
series->append(“Joe”, 2);
series->append(“Andy”, 3);
series->append(“Barbara”, 4);
series->append(“Axel”, 5);
QPieSlice* slice = series->slices().at(1);
slice->setExploded();
slice->setLabelVisible();
slice->setPen(QPen(Qt::darkGreen, 2));
slice->setBrush(Qt::green);
QChart* chart = new QChart();
chart->addSeries(series);
chart->setTitle(“Simple piechart example”);
chart->legend()->hide();
QChartView* chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(400, 300);
window.show();
return app.exec();
}
wxCode
Home:[http://wxcode.sourceforge.net/]
该项目专门提供组件来扩展 wxWidgets 的功能。它里面提供了好几种图表的组件(wxChart、wxFreeChart、wxPlotCtrl)。
wxMathPlot
Home:[http://wxmathplot.sourceforge.net/]
看名称就知道它是跟 wxWidgets 搭配的。效果图参见“[http://wxmathplot.sourceforge.net/screenshot.shtml 这里]”
—-
= 7 文本用户界面(TUI) =
== 7.1 命令行参数 ==
getopt
Home:[https://www.gnu.org/software/libc/manual/html_node/Getopt.html]
Links:[https://en.wikipedia.org/wiki/Getopt Wikipedia]
这是标准C用来处理命令行参数的老牌函数,诞生于上世纪80年代初期。
它有很多种不同的实现,如今用得最多的是 GNU C Library 的实现。GNU 还实现了一个增强版 getopt_long。
代码示例
int main(int argc, char* argv[])
{
int digit_optind = 0;
int aopt = 0, bopt = 0;
char* copt = NULL;
char* dopt = NULL;
int c;
while( (c = getopt(argc, argv, “abc:d:012”)) != -1)
{
int this_option_optind = optind ? optind : 1;
switch(c)
{
case ‘0’:
case ‘1’:
case ‘2’:
if(digit_optind != 0 && digit_optind != this_option_optind)
{
printf(“digits occur in two different argv-elements.\n”);
}
digit_optind = this_option_optind;
printf(“option %c\n”, c);
break;
case ‘a’:
printf(“option a\n”);
aopt = 1;
break;
case ‘b’:
printf(“option b\n”);
bopt = 1;
break;
case ‘c’:
printf(“option c with value ‘%s’\n”, optarg);
copt = optarg;
break;
case ‘d’:
printf(“option d with value ‘%s’\n”, optarg);
dopt = optarg;
break;
case ‘?’:
break;
default:
printf(“?? getopt returned character code 0%o ??\n”, c);
}
}
if(optind < argc) { printf("non-option ARGV-elements: "); while(optind < argc) { printf("%s ", argv[optind++]); } printf("\n"); } exit (0);}
Boost.Program_options
Docs:[http://boost.org/libs/program_options]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“处理命令行参数”的功能。
它的功能很丰富,但是比较重型。
== 7.2 文本终端 ==
ncurses
Home:[https://www.gnu.org/software/ncurses/]
Links:[https://en.wikipedia.org/wiki/Ncurses Wikipedia] [https://zh.wikipedia.org/wiki/Ncurses 维基百科]
ncurses 是“new curses”的缩略词,它是 [https://en.wikipedia.org/wiki/Curses_(programming_library) curses] 库的自由软件克隆,诞生于1993年。
大名鼎鼎的 [https://en.wikipedia.org/wiki/Eric_S._Raymond Eric S. Raymond] 曾参与早期版本的开发。
= 8 网络 =
== 8.1 链路层 & 网络层 ==
libpcap
Home:[http://www.tcpdump.org/]
Links:[https://en.wikipedia.org/wiki/Pcap Wikipedia]
很著名的 Sniffer 抓包库,基于 C 语言开发。
代码示例——一个简单的抓包示例
WinPcap
Home:[http://www.winpcap.org/]
Links:[https://en.wikipedia.org/wiki/Pcap Wikipedia]
它是 libpcap 在 Windows 系统下的移植。