[{"data":1,"prerenderedAt":5638},["ShallowReactive",2],{"wiki-page-\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin":3,"wiki-doc-items-\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin":5217,"language-switcher-data-\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin":5622,"wiki-i18n-paths-\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin":5637},{"id":4,"title":5,"body":6,"canonicalPath":5199,"chapterDepth":219,"chapterOrder":5200,"date":5201,"description":26,"docI18nKey":5202,"docKey":5203,"docRoot":5204,"docTitle":5205,"extension":5206,"i18nKey":5207,"isBlogPost":5208,"isWikiDoc":246,"isWikiIndex":5208,"layout":5209,"legacyPath":5209,"locale":5210,"localeSlug":5211,"meta":5212,"navigation":246,"path":5199,"seo":5213,"sourcePath":5214,"sourceStem":5207,"stem":5215,"wikiDepth":71,"__hash__":5216},"content\u002F_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0300-串口通信.md","serial communication",{"type":7,"value":8,"toc":5147},"minimark",[9,16,19,30,37,40,45,52,57,60,86,89,105,109,112,138,141,147,150,156,167,169,176,180,186,192,197,201,944,951,955,958,978,981,994,997,1033,1037,1040,1046,1049,1054,1057,1061,1068,1072,1079,1082,1085,1094,1105,1114,1117,1123,1126,1132,1135,1138,1140,1146,1149,1154,1157,1641,1645,1648,1650,1670,1673,1703,1706,1724,1727,1730,1736,1739,1753,1756,1762,1765,1768,1774,1777,1780,1786,1792,1795,1802,1804,1810,1813,1816,1843,1846,2517,2521,2524,2526,2546,2548,2578,2581,2597,2600,2603,2609,2615,2621,2624,2630,2633,2638,2641,2655,2658,2662,2667,2702,2705,2732,2735,2747,2750,2752,2756,2759,2762,2765,2768,3709,3713,3716,3718,3738,3740,3770,3773,3811,3814,3817,3823,3826,3832,3839,3842,3845,3857,3864,3870,3874,3899,3905,3908,3912,3962,3965,3984,3986,3990,3993,3996,4002,4009,4015,4018,4911,4915,4918,4920,4940,4942,4952,4955,4985,4988,4991,4997,4999,5004,5007,5014,5017,5038,5041,5047,5067,5070,5073,5103,5108,5110,5114,5143],[10,11,12],"blockquote",{},[13,14,15],"p",{},"Serial ports are one of the most common communication methods in robotics: host computer ROS2 \u002F Linux programs communicate with STM32, ESP32, and lower-level control boards via USB-TTL, USB-CAN to serial adapters, CH340, CP2102, FT232, and other devices.",[13,17,18],{},"This section still follows the order:",[20,21,27],"pre",{"className":22,"code":24,"language":25,"meta":26},[23],"language-text","先写普通 main() 里的同步示例\n再写普通 main() 里的异步示例\n最后写类封装版本\n","text","",[28,29,24],"code",{"__ignoreMap":26},[13,31,32,33,36],{},"All asynchronous callbacks uniformly use ",[28,34,35],{},"std::bind",".",[38,39],"hr",{},[41,42,44],"h2",{"id":43},"setting-up-a-virtual-serial-port-test-environment-on-linux","Setting Up a Virtual Serial Port Test Environment on Linux",[13,46,47,48,51],{},"If you don't have a real STM32 in hand, you can use ",[28,49,50],{},"socat"," to create a pair of virtual serial ports.",[53,54,56],"h3",{"id":55},"install-socat","Install socat",[13,58,59],{},"Ubuntu \u002F Debian：",[20,61,65],{"className":62,"code":63,"language":64,"meta":26,"style":26},"language-bash shiki shiki-themes github-light github-dark","sudo apt install socat\n","bash",[28,66,67],{"__ignoreMap":26},[68,69,72,76,80,83],"span",{"class":70,"line":71},"line",1,[68,73,75],{"class":74},"sScJk","sudo",[68,77,79],{"class":78},"sZZnC"," apt",[68,81,82],{"class":78}," install",[68,84,85],{"class":78}," socat\n",[13,87,88],{},"Fedora：",[20,90,92],{"className":62,"code":91,"language":64,"meta":26,"style":26},"sudo dnf install socat\n",[28,93,94],{"__ignoreMap":26},[68,95,96,98,101,103],{"class":70,"line":71},[68,97,75],{"class":74},[68,99,100],{"class":78}," dnf",[68,102,82],{"class":78},[68,104,85],{"class":78},[53,106,108],{"id":107},"create-a-pair-of-virtual-serial-ports","Create a pair of virtual serial ports.",[13,110,111],{},"Open a new terminal and run:",[20,113,115],{"className":62,"code":114,"language":64,"meta":26,"style":26},"socat -d -d pty,raw,echo=0 pty,raw,echo=0\n",[28,116,117],{"__ignoreMap":26},[68,118,119,121,125,127,130,133,135],{"class":70,"line":71},[68,120,50],{"class":74},[68,122,124],{"class":123},"sj4cs"," -d",[68,126,124],{"class":123},[68,128,129],{"class":78}," pty,raw,echo=",[68,131,132],{"class":123},"0",[68,134,129],{"class":78},[68,136,137],{"class":123},"0\n",[13,139,140],{},"You will see output similar to:",[20,142,145],{"className":143,"code":144,"language":25,"meta":26},[23],"2026\u002F05\u002F24 12:00:00 socat[12345] N PTY is \u002Fdev\u002Fpts\u002F3\n2026\u002F05\u002F24 12:00:00 socat[12345] N PTY is \u002Fdev\u002Fpts\u002F4\n2026\u002F05\u002F24 12:00:00 socat[12345] N starting data transfer loop with FDs [5,5] and [7,7]\n",[28,146,144],{"__ignoreMap":26},[13,148,149],{},"This means:",[20,151,154],{"className":152,"code":153,"language":25,"meta":26},[23],"\u002Fdev\u002Fpts\u002F3 和 \u002Fdev\u002Fpts\u002F4 是一对互通的虚拟串口\n程序写 \u002Fdev\u002Fpts\u002F3，另一个终端读 \u002Fdev\u002Fpts\u002F4 就能看到\n程序读 \u002Fdev\u002Fpts\u002F3，另一个终端写 \u002Fdev\u002Fpts\u002F4 就能发给程序\n",[28,155,153],{"__ignoreMap":26},[13,157,158,159,162,163,166],{},"The following examples assume the program uses ",[28,160,161],{},"\u002Fdev\u002Fpts\u002F3",", and the other terminal uses ",[28,164,165],{},"\u002Fdev\u002Fpts\u002F4",". You should modify according to the actual output of your own terminal.",[38,168],{},[41,170,172,173],{"id":171},"example-1-synchronously-open-the-serial-port-and-send-a-line-in-ordinary-main","Example 1: Synchronously open the serial port and send a line in ordinary ",[28,174,175],{},"main()",[53,177,179],{"id":178},"program-objective","program objective",[13,181,182,183,185],{},"The program opens serial port ",[28,184,161],{},", sets the baud rate to 115200, then sends:",[20,187,190],{"className":188,"code":189,"language":25,"meta":26},[23],"hello serial\n",[28,191,189],{"__ignoreMap":26},[13,193,194,195,36],{},"Another terminal reads this line of data from ",[28,196,165],{},[53,198,200],{"id":199},"full-code","Full code",[20,202,206],{"className":203,"code":204,"language":205,"meta":26,"style":26},"language-cpp shiki shiki-themes github-light github-dark","#include \u003Cboost\u002Fasio.hpp>\n#include \u003Cboost\u002Fsystem\u002Ferror_code.hpp>\n#include \u003Ciostream>\n#include \u003Cstring>\n\nint main(int argc, char* argv[])\n{\n    \u002F\u002F 程序从 main 函数开始执行，argc\u002Fargv 用来接收命令行参数。\n    std::string port_name = \"\u002Fdev\u002Fpts\u002F3\";\n\n    if (argc >= 2)\n    {\n        port_name = argv[1];\n    }\n\n    \u002F\u002F io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n    \u002F\u002F serial_port 表示串口设备，后续读写都通过它完成。\n    boost::asio::serial_port serial(io);\n    boost::system::error_code ec;\n\n    std::cout \u003C\u003C \"main：准备打开串口 \" \u003C\u003C port_name \u003C\u003C std::endl;\n\n    serial.open(port_name, ec);\n    if (ec)\n    {\n        std::cout \u003C\u003C \"打开串口失败：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n        return 1;\n    }\n\n    serial.set_option(boost::asio::serial_port_base::baud_rate(115200));\n    serial.set_option(boost::asio::serial_port_base::character_size(8));\n    serial.set_option(boost::asio::serial_port_base::parity(\n        boost::asio::serial_port_base::parity::none));\n    serial.set_option(boost::asio::serial_port_base::stop_bits(\n        boost::asio::serial_port_base::stop_bits::one));\n    serial.set_option(boost::asio::serial_port_base::flow_control(\n        boost::asio::serial_port_base::flow_control::none));\n\n    std::string msg = \"hello serial\\n\";\n\n    \u002F\u002F 把缓冲区中的数据写入连接。\n    std::size_t n = boost::asio::write(serial, boost::asio::buffer(msg), ec);\n    if (ec)\n    {\n        std::cout \u003C\u003C \"发送失败：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n        return 1;\n    }\n\n    std::cout \u003C\u003C \"main：发送成功，字节数 = \" \u003C\u003C n \u003C\u003C std::endl;\n    std::cout \u003C\u003C \"main：程序结束\" \u003C\u003C std::endl;\n\n    return 0;\n}\n","cpp",[28,207,208,217,225,233,241,248,279,285,292,310,315,333,339,356,362,367,373,388,394,412,425,430,458,463,475,483,488,518,529,534,539,574,605,632,653,679,699,725,744,749,770,775,781,825,832,837,863,872,877,882,904,922,927,938],{"__ignoreMap":26},[68,209,210,214],{"class":70,"line":71},[68,211,213],{"class":212},"szBVR","#include",[68,215,216],{"class":78}," \u003Cboost\u002Fasio.hpp>\n",[68,218,220,222],{"class":70,"line":219},2,[68,221,213],{"class":212},[68,223,224],{"class":78}," \u003Cboost\u002Fsystem\u002Ferror_code.hpp>\n",[68,226,228,230],{"class":70,"line":227},3,[68,229,213],{"class":212},[68,231,232],{"class":78}," \u003Ciostream>\n",[68,234,236,238],{"class":70,"line":235},4,[68,237,213],{"class":212},[68,239,240],{"class":78}," \u003Cstring>\n",[68,242,244],{"class":70,"line":243},5,[68,245,247],{"emptyLinePlaceholder":246},true,"\n",[68,249,251,254,257,261,263,267,270,273,276],{"class":70,"line":250},6,[68,252,253],{"class":212},"int",[68,255,256],{"class":74}," main",[68,258,260],{"class":259},"sVt8B","(",[68,262,253],{"class":212},[68,264,266],{"class":265},"s4XuR"," argc",[68,268,269],{"class":259},", ",[68,271,272],{"class":212},"char*",[68,274,275],{"class":265}," argv",[68,277,278],{"class":259},"[])\n",[68,280,282],{"class":70,"line":281},7,[68,283,284],{"class":259},"{\n",[68,286,288],{"class":70,"line":287},8,[68,289,291],{"class":290},"sJ8bj","    \u002F\u002F 程序从 main 函数开始执行，argc\u002Fargv 用来接收命令行参数。\n",[68,293,295,298,301,304,307],{"class":70,"line":294},9,[68,296,297],{"class":74},"    std",[68,299,300],{"class":259},"::string port_name ",[68,302,303],{"class":212},"=",[68,305,306],{"class":78}," \"\u002Fdev\u002Fpts\u002F3\"",[68,308,309],{"class":259},";\n",[68,311,313],{"class":70,"line":312},10,[68,314,247],{"emptyLinePlaceholder":246},[68,316,318,321,324,327,330],{"class":70,"line":317},11,[68,319,320],{"class":212},"    if",[68,322,323],{"class":259}," (argc ",[68,325,326],{"class":212},">=",[68,328,329],{"class":123}," 2",[68,331,332],{"class":259},")\n",[68,334,336],{"class":70,"line":335},12,[68,337,338],{"class":259},"    {\n",[68,340,342,345,347,350,353],{"class":70,"line":341},13,[68,343,344],{"class":259},"        port_name ",[68,346,303],{"class":212},[68,348,349],{"class":259}," argv[",[68,351,352],{"class":123},"1",[68,354,355],{"class":259},"];\n",[68,357,359],{"class":70,"line":358},14,[68,360,361],{"class":259},"    }\n",[68,363,365],{"class":70,"line":364},15,[68,366,247],{"emptyLinePlaceholder":246},[68,368,370],{"class":70,"line":369},16,[68,371,372],{"class":290},"    \u002F\u002F io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n",[68,374,376,379,382,385],{"class":70,"line":375},17,[68,377,378],{"class":74},"    boost",[68,380,381],{"class":259},"::",[68,383,384],{"class":74},"asio",[68,386,387],{"class":259},"::io_context io;\n",[68,389,391],{"class":70,"line":390},18,[68,392,393],{"class":290},"    \u002F\u002F serial_port 表示串口设备，后续读写都通过它完成。\n",[68,395,397,399,401,403,406,409],{"class":70,"line":396},19,[68,398,378],{"class":74},[68,400,381],{"class":259},[68,402,384],{"class":74},[68,404,405],{"class":259},"::serial_port ",[68,407,408],{"class":74},"serial",[68,410,411],{"class":259},"(io);\n",[68,413,415,417,419,422],{"class":70,"line":414},20,[68,416,378],{"class":74},[68,418,381],{"class":259},[68,420,421],{"class":74},"system",[68,423,424],{"class":259},"::error_code ec;\n",[68,426,428],{"class":70,"line":427},21,[68,429,247],{"emptyLinePlaceholder":246},[68,431,433,435,438,441,444,447,450,452,455],{"class":70,"line":432},22,[68,434,297],{"class":74},[68,436,437],{"class":259},"::cout ",[68,439,440],{"class":212},"\u003C\u003C",[68,442,443],{"class":78}," \"main：准备打开串口 \"",[68,445,446],{"class":212}," \u003C\u003C",[68,448,449],{"class":259}," port_name ",[68,451,440],{"class":212},[68,453,454],{"class":74}," std",[68,456,457],{"class":259},"::endl;\n",[68,459,461],{"class":70,"line":460},23,[68,462,247],{"emptyLinePlaceholder":246},[68,464,466,469,472],{"class":70,"line":465},24,[68,467,468],{"class":259},"    serial.",[68,470,471],{"class":74},"open",[68,473,474],{"class":259},"(port_name, ec);\n",[68,476,478,480],{"class":70,"line":477},25,[68,479,320],{"class":212},[68,481,482],{"class":259}," (ec)\n",[68,484,486],{"class":70,"line":485},26,[68,487,338],{"class":259},[68,489,491,494,496,498,501,503,506,509,512,514,516],{"class":70,"line":490},27,[68,492,493],{"class":74},"        std",[68,495,437],{"class":259},[68,497,440],{"class":212},[68,499,500],{"class":78}," \"打开串口失败：\"",[68,502,446],{"class":212},[68,504,505],{"class":259}," ec.",[68,507,508],{"class":74},"message",[68,510,511],{"class":259},"() ",[68,513,440],{"class":212},[68,515,454],{"class":74},[68,517,457],{"class":259},[68,519,521,524,527],{"class":70,"line":520},28,[68,522,523],{"class":212},"        return",[68,525,526],{"class":123}," 1",[68,528,309],{"class":259},[68,530,532],{"class":70,"line":531},29,[68,533,361],{"class":259},[68,535,537],{"class":70,"line":536},30,[68,538,247],{"emptyLinePlaceholder":246},[68,540,542,544,547,549,552,554,556,558,561,563,566,568,571],{"class":70,"line":541},31,[68,543,468],{"class":259},[68,545,546],{"class":74},"set_option",[68,548,260],{"class":259},[68,550,551],{"class":74},"boost",[68,553,381],{"class":259},[68,555,384],{"class":74},[68,557,381],{"class":259},[68,559,560],{"class":74},"serial_port_base",[68,562,381],{"class":259},[68,564,565],{"class":74},"baud_rate",[68,567,260],{"class":259},[68,569,570],{"class":123},"115200",[68,572,573],{"class":259},"));\n",[68,575,577,579,581,583,585,587,589,591,593,595,598,600,603],{"class":70,"line":576},32,[68,578,468],{"class":259},[68,580,546],{"class":74},[68,582,260],{"class":259},[68,584,551],{"class":74},[68,586,381],{"class":259},[68,588,384],{"class":74},[68,590,381],{"class":259},[68,592,560],{"class":74},[68,594,381],{"class":259},[68,596,597],{"class":74},"character_size",[68,599,260],{"class":259},[68,601,602],{"class":123},"8",[68,604,573],{"class":259},[68,606,608,610,612,614,616,618,620,622,624,626,629],{"class":70,"line":607},33,[68,609,468],{"class":259},[68,611,546],{"class":74},[68,613,260],{"class":259},[68,615,551],{"class":74},[68,617,381],{"class":259},[68,619,384],{"class":74},[68,621,381],{"class":259},[68,623,560],{"class":74},[68,625,381],{"class":259},[68,627,628],{"class":74},"parity",[68,630,631],{"class":259},"(\n",[68,633,635,638,640,642,644,646,648,650],{"class":70,"line":634},34,[68,636,637],{"class":74},"        boost",[68,639,381],{"class":259},[68,641,384],{"class":74},[68,643,381],{"class":259},[68,645,560],{"class":74},[68,647,381],{"class":259},[68,649,628],{"class":74},[68,651,652],{"class":259},"::none));\n",[68,654,656,658,660,662,664,666,668,670,672,674,677],{"class":70,"line":655},35,[68,657,468],{"class":259},[68,659,546],{"class":74},[68,661,260],{"class":259},[68,663,551],{"class":74},[68,665,381],{"class":259},[68,667,384],{"class":74},[68,669,381],{"class":259},[68,671,560],{"class":74},[68,673,381],{"class":259},[68,675,676],{"class":74},"stop_bits",[68,678,631],{"class":259},[68,680,682,684,686,688,690,692,694,696],{"class":70,"line":681},36,[68,683,637],{"class":74},[68,685,381],{"class":259},[68,687,384],{"class":74},[68,689,381],{"class":259},[68,691,560],{"class":74},[68,693,381],{"class":259},[68,695,676],{"class":74},[68,697,698],{"class":259},"::one));\n",[68,700,702,704,706,708,710,712,714,716,718,720,723],{"class":70,"line":701},37,[68,703,468],{"class":259},[68,705,546],{"class":74},[68,707,260],{"class":259},[68,709,551],{"class":74},[68,711,381],{"class":259},[68,713,384],{"class":74},[68,715,381],{"class":259},[68,717,560],{"class":74},[68,719,381],{"class":259},[68,721,722],{"class":74},"flow_control",[68,724,631],{"class":259},[68,726,728,730,732,734,736,738,740,742],{"class":70,"line":727},38,[68,729,637],{"class":74},[68,731,381],{"class":259},[68,733,384],{"class":74},[68,735,381],{"class":259},[68,737,560],{"class":74},[68,739,381],{"class":259},[68,741,722],{"class":74},[68,743,652],{"class":259},[68,745,747],{"class":70,"line":746},39,[68,748,247],{"emptyLinePlaceholder":246},[68,750,752,754,757,759,762,765,768],{"class":70,"line":751},40,[68,753,297],{"class":74},[68,755,756],{"class":259},"::string msg ",[68,758,303],{"class":212},[68,760,761],{"class":78}," \"hello serial",[68,763,764],{"class":123},"\\n",[68,766,767],{"class":78},"\"",[68,769,309],{"class":259},[68,771,773],{"class":70,"line":772},41,[68,774,247],{"emptyLinePlaceholder":246},[68,776,778],{"class":70,"line":777},42,[68,779,780],{"class":290},"    \u002F\u002F 把缓冲区中的数据写入连接。\n",[68,782,784,786,788,791,794,796,799,801,803,805,808,811,813,815,817,819,822],{"class":70,"line":783},43,[68,785,297],{"class":74},[68,787,381],{"class":259},[68,789,790],{"class":212},"size_t",[68,792,793],{"class":259}," n ",[68,795,303],{"class":212},[68,797,798],{"class":74}," boost",[68,800,381],{"class":259},[68,802,384],{"class":74},[68,804,381],{"class":259},[68,806,807],{"class":74},"write",[68,809,810],{"class":259},"(serial, ",[68,812,551],{"class":74},[68,814,381],{"class":259},[68,816,384],{"class":74},[68,818,381],{"class":259},[68,820,821],{"class":74},"buffer",[68,823,824],{"class":259},"(msg), ec);\n",[68,826,828,830],{"class":70,"line":827},44,[68,829,320],{"class":212},[68,831,482],{"class":259},[68,833,835],{"class":70,"line":834},45,[68,836,338],{"class":259},[68,838,840,842,844,846,849,851,853,855,857,859,861],{"class":70,"line":839},46,[68,841,493],{"class":74},[68,843,437],{"class":259},[68,845,440],{"class":212},[68,847,848],{"class":78}," \"发送失败：\"",[68,850,446],{"class":212},[68,852,505],{"class":259},[68,854,508],{"class":74},[68,856,511],{"class":259},[68,858,440],{"class":212},[68,860,454],{"class":74},[68,862,457],{"class":259},[68,864,866,868,870],{"class":70,"line":865},47,[68,867,523],{"class":212},[68,869,526],{"class":123},[68,871,309],{"class":259},[68,873,875],{"class":70,"line":874},48,[68,876,361],{"class":259},[68,878,880],{"class":70,"line":879},49,[68,881,247],{"emptyLinePlaceholder":246},[68,883,885,887,889,891,894,896,898,900,902],{"class":70,"line":884},50,[68,886,297],{"class":74},[68,888,437],{"class":259},[68,890,440],{"class":212},[68,892,893],{"class":78}," \"main：发送成功，字节数 = \"",[68,895,446],{"class":212},[68,897,793],{"class":259},[68,899,440],{"class":212},[68,901,454],{"class":74},[68,903,457],{"class":259},[68,905,907,909,911,913,916,918,920],{"class":70,"line":906},51,[68,908,297],{"class":74},[68,910,437],{"class":259},[68,912,440],{"class":212},[68,914,915],{"class":78}," \"main：程序结束\"",[68,917,446],{"class":212},[68,919,454],{"class":74},[68,921,457],{"class":259},[68,923,925],{"class":70,"line":924},52,[68,926,247],{"emptyLinePlaceholder":246},[68,928,930,933,936],{"class":70,"line":929},53,[68,931,932],{"class":212},"    return",[68,934,935],{"class":123}," 0",[68,937,309],{"class":259},[68,939,941],{"class":70,"line":940},54,[68,942,943],{"class":259},"}\n",[13,945,946,950],{},[947,948,949],"strong",{},"Running Results",": See below for “Execution Output and Timeline”; specific times and sequences may vary slightly with the environment if the example involves timers, threads, networks, or external devices.",[53,952,954],{"id":953},"compile-and-run","Compile and run",[13,956,957],{},"Terminal 1: Create virtual serial port.",[20,959,960],{"className":62,"code":114,"language":64,"meta":26,"style":26},[28,961,962],{"__ignoreMap":26},[68,963,964,966,968,970,972,974,976],{"class":70,"line":71},[68,965,50],{"class":74},[68,967,124],{"class":123},[68,969,124],{"class":123},[68,971,129],{"class":78},[68,973,132],{"class":123},[68,975,129],{"class":78},[68,977,137],{"class":123},[13,979,980],{},"Terminal 2: Listen on the other end.",[20,982,984],{"className":62,"code":983,"language":64,"meta":26,"style":26},"cat \u002Fdev\u002Fpts\u002F4\n",[28,985,986],{"__ignoreMap":26},[68,987,988,991],{"class":70,"line":71},[68,989,990],{"class":74},"cat",[68,992,993],{"class":78}," \u002Fdev\u002Fpts\u002F4\n",[13,995,996],{},"Terminal 3: Compile and run the program.",[20,998,1000],{"className":62,"code":999,"language":64,"meta":26,"style":26},"g++ demo1_serial_write.cpp -o demo1_serial_write -std=c++17 -lboost_system -pthread\n.\u002Fdemo1_serial_write \u002Fdev\u002Fpts\u002F3\n",[28,1001,1002,1025],{"__ignoreMap":26},[68,1003,1004,1007,1010,1013,1016,1019,1022],{"class":70,"line":71},[68,1005,1006],{"class":74},"g++",[68,1008,1009],{"class":78}," demo1_serial_write.cpp",[68,1011,1012],{"class":123}," -o",[68,1014,1015],{"class":78}," demo1_serial_write",[68,1017,1018],{"class":123}," -std=c++17",[68,1020,1021],{"class":123}," -lboost_system",[68,1023,1024],{"class":123}," -pthread\n",[68,1026,1027,1030],{"class":70,"line":219},[68,1028,1029],{"class":74},".\u002Fdemo1_serial_write",[68,1031,1032],{"class":78}," \u002Fdev\u002Fpts\u002F3\n",[53,1034,1036],{"id":1035},"execution-output-and-chronological-order","Execution output and chronological order",[13,1038,1039],{},"Program terminal output:",[20,1041,1044],{"className":1042,"code":1043,"language":25,"meta":26},[23],"main：准备打开串口 \u002Fdev\u002Fpts\u002F3\nmain：发送成功，字节数 = 13\nmain：程序结束\n",[28,1045,1043],{"__ignoreMap":26},[13,1047,1048],{},"Monitor terminal output:",[20,1050,1052],{"className":1051,"code":189,"language":25,"meta":26},[23],[28,1053,189],{"__ignoreMap":26},[13,1055,1056],{},"This example has virtually no noticeable delay, and the program ends immediately after sending is complete.",[53,1058,1060],{"id":1059},"points-to-note-for-this-example","Points to note for this example",[13,1062,1063,1064,1067],{},"This is a synchronous serial port write. ",[28,1065,1066],{},"boost::asio::write()"," will block until the data is written or an error occurs.",[53,1069,1071],{"id":1070},"key-function-explanation","Key Function Explanation",[1073,1074,1076],"h4",{"id":1075},"serialopenport_name-ec",[28,1077,1078],{},"serial.open(port_name, ec)",[13,1080,1081],{},"Purpose: Open the serial port device.",[13,1083,1084],{},"Parameter:",[20,1086,1088],{"className":203,"code":1087,"language":205,"meta":26,"style":26},"port_name\n",[28,1089,1090],{"__ignoreMap":26},[68,1091,1092],{"class":70,"line":71},[68,1093,1087],{"class":259},[13,1095,1096,1097,269,1100,269,1103,36],{},"For example, ",[28,1098,1099],{},"\u002Fdev\u002FttyUSB0",[28,1101,1102],{},"\u002Fdev\u002FttyACM0",[28,1104,161],{},[20,1106,1108],{"className":203,"code":1107,"language":205,"meta":26,"style":26},"ec\n",[28,1109,1110],{"__ignoreMap":26},[68,1111,1112],{"class":70,"line":71},[68,1113,1107],{"class":259},[13,1115,1116],{},"Used to receive error messages. This approach does not throw exceptions, making it more suitable for tutorials and robotics engineering.",[1073,1118,1120],{"id":1119},"serialset_option",[28,1121,1122],{},"serial.set_option(...)",[13,1124,1125],{},"Function: Set serial port parameters, such as baud rate, data bits, parity bit, stop bits, and flow control.",[1073,1127,1129],{"id":1128},"boostasiowriteserial-boostasiobuffermsg-ec",[28,1130,1131],{},"boost::asio::write(serial, boost::asio::buffer(msg), ec)",[13,1133,1134],{},"Purpose: Synchronously write data.",[13,1136,1137],{},"Return value: the number of bytes actually written.",[38,1139],{},[41,1141,1143,1144],{"id":1142},"example-2-synchronously-read-a-line-of-serial-data-in-a-normal-main","Example 2: Synchronously read a line of serial data in a normal ",[28,1145,175],{},[53,1147,179],{"id":1148},"program-objective-1",[13,1150,1151,1152,36],{},"The program opens the serial port and blocks waiting until it receives ",[28,1153,764],{},[53,1155,200],{"id":1156},"full-code-1",[20,1158,1160],{"className":203,"code":1159,"language":205,"meta":26,"style":26},"#include \u003Cboost\u002Fasio.hpp>\n#include \u003Cboost\u002Fsystem\u002Ferror_code.hpp>\n#include \u003Ciostream>\n#include \u003Cistream>\n#include \u003Cstring>\n\nint main(int argc, char* argv[])\n{\n    \u002F\u002F 程序从 main 函数开始执行，argc\u002Fargv 用来接收命令行参数。\n    std::string port_name = \"\u002Fdev\u002Fpts\u002F3\";\n\n    if (argc >= 2)\n    {\n        port_name = argv[1];\n    }\n\n    \u002F\u002F io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n    \u002F\u002F serial_port 表示串口设备，后续读写都通过它完成。\n    boost::asio::serial_port serial(io);\n    boost::system::error_code ec;\n\n    serial.open(port_name, ec);\n    if (ec)\n    {\n        std::cout \u003C\u003C \"打开串口失败：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n        return 1;\n    }\n\n    \u002F\u002F 设置串口或 socket 参数，例如波特率、数据位或超时相关配置。\n    serial.set_option(boost::asio::serial_port_base::baud_rate(115200));\n\n    boost::asio::streambuf buffer;\n\n    std::cout \u003C\u003C \"main：等待串口收到一行数据，以换行符结束\" \u003C\u003C std::endl;\n\n    std::size_t n = boost::asio::read_until(serial, buffer, '\\n', ec);\n    if (ec)\n    {\n        std::cout \u003C\u003C \"读取失败：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n        return 1;\n    }\n\n    std::istream is(&buffer);\n    std::string line;\n    std::getline(is, line);\n\n    std::cout \u003C\u003C \"main：读取到字节数 = \" \u003C\u003C n \u003C\u003C std::endl;\n    std::cout \u003C\u003C \"main：读取到一行 = \" \u003C\u003C line \u003C\u003C std::endl;\n\n    return 0;\n}\n",[28,1161,1162,1168,1174,1180,1187,1193,1197,1217,1221,1225,1237,1241,1253,1257,1269,1273,1277,1281,1291,1295,1309,1319,1323,1331,1337,1341,1365,1373,1377,1381,1386,1414,1418,1429,1433,1450,1454,1490,1496,1500,1525,1533,1537,1541,1559,1566,1578,1582,1603,1625,1629,1637],{"__ignoreMap":26},[68,1163,1164,1166],{"class":70,"line":71},[68,1165,213],{"class":212},[68,1167,216],{"class":78},[68,1169,1170,1172],{"class":70,"line":219},[68,1171,213],{"class":212},[68,1173,224],{"class":78},[68,1175,1176,1178],{"class":70,"line":227},[68,1177,213],{"class":212},[68,1179,232],{"class":78},[68,1181,1182,1184],{"class":70,"line":235},[68,1183,213],{"class":212},[68,1185,1186],{"class":78}," \u003Cistream>\n",[68,1188,1189,1191],{"class":70,"line":243},[68,1190,213],{"class":212},[68,1192,240],{"class":78},[68,1194,1195],{"class":70,"line":250},[68,1196,247],{"emptyLinePlaceholder":246},[68,1198,1199,1201,1203,1205,1207,1209,1211,1213,1215],{"class":70,"line":281},[68,1200,253],{"class":212},[68,1202,256],{"class":74},[68,1204,260],{"class":259},[68,1206,253],{"class":212},[68,1208,266],{"class":265},[68,1210,269],{"class":259},[68,1212,272],{"class":212},[68,1214,275],{"class":265},[68,1216,278],{"class":259},[68,1218,1219],{"class":70,"line":287},[68,1220,284],{"class":259},[68,1222,1223],{"class":70,"line":294},[68,1224,291],{"class":290},[68,1226,1227,1229,1231,1233,1235],{"class":70,"line":312},[68,1228,297],{"class":74},[68,1230,300],{"class":259},[68,1232,303],{"class":212},[68,1234,306],{"class":78},[68,1236,309],{"class":259},[68,1238,1239],{"class":70,"line":317},[68,1240,247],{"emptyLinePlaceholder":246},[68,1242,1243,1245,1247,1249,1251],{"class":70,"line":335},[68,1244,320],{"class":212},[68,1246,323],{"class":259},[68,1248,326],{"class":212},[68,1250,329],{"class":123},[68,1252,332],{"class":259},[68,1254,1255],{"class":70,"line":341},[68,1256,338],{"class":259},[68,1258,1259,1261,1263,1265,1267],{"class":70,"line":358},[68,1260,344],{"class":259},[68,1262,303],{"class":212},[68,1264,349],{"class":259},[68,1266,352],{"class":123},[68,1268,355],{"class":259},[68,1270,1271],{"class":70,"line":364},[68,1272,361],{"class":259},[68,1274,1275],{"class":70,"line":369},[68,1276,247],{"emptyLinePlaceholder":246},[68,1278,1279],{"class":70,"line":375},[68,1280,372],{"class":290},[68,1282,1283,1285,1287,1289],{"class":70,"line":390},[68,1284,378],{"class":74},[68,1286,381],{"class":259},[68,1288,384],{"class":74},[68,1290,387],{"class":259},[68,1292,1293],{"class":70,"line":396},[68,1294,393],{"class":290},[68,1296,1297,1299,1301,1303,1305,1307],{"class":70,"line":414},[68,1298,378],{"class":74},[68,1300,381],{"class":259},[68,1302,384],{"class":74},[68,1304,405],{"class":259},[68,1306,408],{"class":74},[68,1308,411],{"class":259},[68,1310,1311,1313,1315,1317],{"class":70,"line":427},[68,1312,378],{"class":74},[68,1314,381],{"class":259},[68,1316,421],{"class":74},[68,1318,424],{"class":259},[68,1320,1321],{"class":70,"line":432},[68,1322,247],{"emptyLinePlaceholder":246},[68,1324,1325,1327,1329],{"class":70,"line":460},[68,1326,468],{"class":259},[68,1328,471],{"class":74},[68,1330,474],{"class":259},[68,1332,1333,1335],{"class":70,"line":465},[68,1334,320],{"class":212},[68,1336,482],{"class":259},[68,1338,1339],{"class":70,"line":477},[68,1340,338],{"class":259},[68,1342,1343,1345,1347,1349,1351,1353,1355,1357,1359,1361,1363],{"class":70,"line":485},[68,1344,493],{"class":74},[68,1346,437],{"class":259},[68,1348,440],{"class":212},[68,1350,500],{"class":78},[68,1352,446],{"class":212},[68,1354,505],{"class":259},[68,1356,508],{"class":74},[68,1358,511],{"class":259},[68,1360,440],{"class":212},[68,1362,454],{"class":74},[68,1364,457],{"class":259},[68,1366,1367,1369,1371],{"class":70,"line":490},[68,1368,523],{"class":212},[68,1370,526],{"class":123},[68,1372,309],{"class":259},[68,1374,1375],{"class":70,"line":520},[68,1376,361],{"class":259},[68,1378,1379],{"class":70,"line":531},[68,1380,247],{"emptyLinePlaceholder":246},[68,1382,1383],{"class":70,"line":536},[68,1384,1385],{"class":290},"    \u002F\u002F 设置串口或 socket 参数，例如波特率、数据位或超时相关配置。\n",[68,1387,1388,1390,1392,1394,1396,1398,1400,1402,1404,1406,1408,1410,1412],{"class":70,"line":541},[68,1389,468],{"class":259},[68,1391,546],{"class":74},[68,1393,260],{"class":259},[68,1395,551],{"class":74},[68,1397,381],{"class":259},[68,1399,384],{"class":74},[68,1401,381],{"class":259},[68,1403,560],{"class":74},[68,1405,381],{"class":259},[68,1407,565],{"class":74},[68,1409,260],{"class":259},[68,1411,570],{"class":123},[68,1413,573],{"class":259},[68,1415,1416],{"class":70,"line":576},[68,1417,247],{"emptyLinePlaceholder":246},[68,1419,1420,1422,1424,1426],{"class":70,"line":607},[68,1421,378],{"class":74},[68,1423,381],{"class":259},[68,1425,384],{"class":74},[68,1427,1428],{"class":259},"::streambuf buffer;\n",[68,1430,1431],{"class":70,"line":634},[68,1432,247],{"emptyLinePlaceholder":246},[68,1434,1435,1437,1439,1441,1444,1446,1448],{"class":70,"line":655},[68,1436,297],{"class":74},[68,1438,437],{"class":259},[68,1440,440],{"class":212},[68,1442,1443],{"class":78}," \"main：等待串口收到一行数据，以换行符结束\"",[68,1445,446],{"class":212},[68,1447,454],{"class":74},[68,1449,457],{"class":259},[68,1451,1452],{"class":70,"line":681},[68,1453,247],{"emptyLinePlaceholder":246},[68,1455,1456,1458,1460,1462,1464,1466,1468,1470,1472,1474,1477,1480,1483,1485,1487],{"class":70,"line":701},[68,1457,297],{"class":74},[68,1459,381],{"class":259},[68,1461,790],{"class":212},[68,1463,793],{"class":259},[68,1465,303],{"class":212},[68,1467,798],{"class":74},[68,1469,381],{"class":259},[68,1471,384],{"class":74},[68,1473,381],{"class":259},[68,1475,1476],{"class":74},"read_until",[68,1478,1479],{"class":259},"(serial, buffer, ",[68,1481,1482],{"class":78},"'",[68,1484,764],{"class":123},[68,1486,1482],{"class":78},[68,1488,1489],{"class":259},", ec);\n",[68,1491,1492,1494],{"class":70,"line":727},[68,1493,320],{"class":212},[68,1495,482],{"class":259},[68,1497,1498],{"class":70,"line":746},[68,1499,338],{"class":259},[68,1501,1502,1504,1506,1508,1511,1513,1515,1517,1519,1521,1523],{"class":70,"line":751},[68,1503,493],{"class":74},[68,1505,437],{"class":259},[68,1507,440],{"class":212},[68,1509,1510],{"class":78}," \"读取失败：\"",[68,1512,446],{"class":212},[68,1514,505],{"class":259},[68,1516,508],{"class":74},[68,1518,511],{"class":259},[68,1520,440],{"class":212},[68,1522,454],{"class":74},[68,1524,457],{"class":259},[68,1526,1527,1529,1531],{"class":70,"line":772},[68,1528,523],{"class":212},[68,1530,526],{"class":123},[68,1532,309],{"class":259},[68,1534,1535],{"class":70,"line":777},[68,1536,361],{"class":259},[68,1538,1539],{"class":70,"line":783},[68,1540,247],{"emptyLinePlaceholder":246},[68,1542,1543,1545,1548,1551,1553,1556],{"class":70,"line":827},[68,1544,297],{"class":74},[68,1546,1547],{"class":259},"::istream ",[68,1549,1550],{"class":74},"is",[68,1552,260],{"class":259},[68,1554,1555],{"class":212},"&",[68,1557,1558],{"class":259},"buffer);\n",[68,1560,1561,1563],{"class":70,"line":834},[68,1562,297],{"class":74},[68,1564,1565],{"class":259},"::string line;\n",[68,1567,1568,1570,1572,1575],{"class":70,"line":839},[68,1569,297],{"class":74},[68,1571,381],{"class":259},[68,1573,1574],{"class":74},"getline",[68,1576,1577],{"class":259},"(is, line);\n",[68,1579,1580],{"class":70,"line":865},[68,1581,247],{"emptyLinePlaceholder":246},[68,1583,1584,1586,1588,1590,1593,1595,1597,1599,1601],{"class":70,"line":874},[68,1585,297],{"class":74},[68,1587,437],{"class":259},[68,1589,440],{"class":212},[68,1591,1592],{"class":78}," \"main：读取到字节数 = \"",[68,1594,446],{"class":212},[68,1596,793],{"class":259},[68,1598,440],{"class":212},[68,1600,454],{"class":74},[68,1602,457],{"class":259},[68,1604,1605,1607,1609,1611,1614,1616,1619,1621,1623],{"class":70,"line":879},[68,1606,297],{"class":74},[68,1608,437],{"class":259},[68,1610,440],{"class":212},[68,1612,1613],{"class":78}," \"main：读取到一行 = \"",[68,1615,446],{"class":212},[68,1617,1618],{"class":259}," line ",[68,1620,440],{"class":212},[68,1622,454],{"class":74},[68,1624,457],{"class":259},[68,1626,1627],{"class":70,"line":884},[68,1628,247],{"emptyLinePlaceholder":246},[68,1630,1631,1633,1635],{"class":70,"line":906},[68,1632,932],{"class":212},[68,1634,935],{"class":123},[68,1636,309],{"class":259},[68,1638,1639],{"class":70,"line":924},[68,1640,943],{"class":259},[13,1642,1643,950],{},[947,1644,949],{},[53,1646,954],{"id":1647},"compile-and-run-1",[13,1649,957],{},[20,1651,1652],{"className":62,"code":114,"language":64,"meta":26,"style":26},[28,1653,1654],{"__ignoreMap":26},[68,1655,1656,1658,1660,1662,1664,1666,1668],{"class":70,"line":71},[68,1657,50],{"class":74},[68,1659,124],{"class":123},[68,1661,124],{"class":123},[68,1663,129],{"class":78},[68,1665,132],{"class":123},[68,1667,129],{"class":78},[68,1669,137],{"class":123},[13,1671,1672],{},"Terminal 2: Run the program.",[20,1674,1676],{"className":62,"code":1675,"language":64,"meta":26,"style":26},"g++ demo2_serial_read_line.cpp -o demo2_serial_read_line -std=c++17 -lboost_system -pthread\n.\u002Fdemo2_serial_read_line \u002Fdev\u002Fpts\u002F3\n",[28,1677,1678,1696],{"__ignoreMap":26},[68,1679,1680,1682,1685,1687,1690,1692,1694],{"class":70,"line":71},[68,1681,1006],{"class":74},[68,1683,1684],{"class":78}," demo2_serial_read_line.cpp",[68,1686,1012],{"class":123},[68,1688,1689],{"class":78}," demo2_serial_read_line",[68,1691,1018],{"class":123},[68,1693,1021],{"class":123},[68,1695,1024],{"class":123},[68,1697,1698,1701],{"class":70,"line":219},[68,1699,1700],{"class":74},".\u002Fdemo2_serial_read_line",[68,1702,1032],{"class":78},[13,1704,1705],{},"Terminal 3: Write data to the other end.",[20,1707,1709],{"className":62,"code":1708,"language":64,"meta":26,"style":26},"echo \"stm32 ok\" > \u002Fdev\u002Fpts\u002F4\n",[28,1710,1711],{"__ignoreMap":26},[68,1712,1713,1716,1719,1722],{"class":70,"line":71},[68,1714,1715],{"class":123},"echo",[68,1717,1718],{"class":78}," \"stm32 ok\"",[68,1720,1721],{"class":212}," >",[68,1723,993],{"class":78},[53,1725,1036],{"id":1726},"execution-output-and-chronological-order-1",[13,1728,1729],{},"Output immediately after program startup:",[20,1731,1734],{"className":1732,"code":1733,"language":25,"meta":26},[23],"main：等待串口收到一行数据，以换行符结束\n",[28,1735,1733],{"__ignoreMap":26},[13,1737,1738],{},"Then the program blocks. In another terminal, execute:",[20,1740,1741],{"className":62,"code":1708,"language":64,"meta":26,"style":26},[28,1742,1743],{"__ignoreMap":26},[68,1744,1745,1747,1749,1751],{"class":70,"line":71},[68,1746,1715],{"class":123},[68,1748,1718],{"class":78},[68,1750,1721],{"class":212},[68,1752,993],{"class":78},[13,1754,1755],{},"The program continues to output:",[20,1757,1760],{"className":1758,"code":1759,"language":25,"meta":26},[23],"main：读取到字节数 = 9\nmain：读取到一行 = stm32 ok\n",[28,1761,1759],{"__ignoreMap":26},[13,1763,1764],{},"The waiting time here depends on when you send the data.",[53,1766,1060],{"id":1767},"points-to-note-for-this-example-1",[13,1769,1770,1773],{},[28,1771,1772],{},"read_until()"," is a synchronous blocking function. It will block until a newline character is received.",[13,1775,1776],{},"If you read the serial port directly like this within a ROS2 callback, it may cause the entire node's response to slow down.",[53,1778,1071],{"id":1779},"key-function-explanation-1",[1073,1781,1783],{"id":1782},"boostasioread_untilserial-buffer-n-ec",[28,1784,1785],{},"boost::asio::read_until(serial, buffer, '\\n', ec)",[13,1787,1788,1789,1791],{},"Function: Read data from the serial port until a newline character ",[28,1790,764],{}," is encountered.",[13,1793,1794],{},"Return value: the number of bytes read at least up to the delimiter.",[13,1796,1797,1798,1801],{},"Note: There may still be extra data in ",[28,1799,1800],{},"streambuf",", so be careful to handle it appropriately during subsequent reads.",[38,1803],{},[41,1805,1807,1808],{"id":1806},"example-3-asynchronously-reading-a-line-of-serial-data-in-a-regular-main","Example 3: Asynchronously reading a line of serial data in a regular ",[28,1809,175],{},[53,1811,179],{"id":1812},"program-objective-2",[13,1814,1815],{},"Change Example 2 to an asynchronous version:",[1817,1818,1819,1826,1832,1835,1838],"ol",{},[1820,1821,1822,1825],"li",{},[28,1823,1824],{},"async_read_until()"," register read task;",[1820,1827,1828,1831],{},[28,1829,1830],{},"io.run()"," start waiting;",[1820,1833,1834],{},"The other end sends a line of data;",[1820,1836,1837],{},"Callback function execution;",[1820,1839,1840,1842],{},[28,1841,1830],{}," return.",[53,1844,200],{"id":1845},"full-code-2",[20,1847,1849],{"className":203,"code":1848,"language":205,"meta":26,"style":26},"#include \u003Cboost\u002Fasio.hpp>\n#include \u003Cboost\u002Fsystem\u002Ferror_code.hpp>\n#include \u003Cfunctional>\n#include \u003Ciostream>\n#include \u003Cistream>\n#include \u003Cstring>\n\nvoid on_read_line(const boost::system::error_code& ec,\n                  std::size_t bytes_transferred,\n                  boost::asio::streambuf* buffer)\n{\n    if (ec)\n    {\n        std::cout \u003C\u003C \"on_read_line：读取失败：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n        return;\n    }\n\n    std::istream is(buffer);\n    std::string line;\n    std::getline(is, line);\n\n    std::cout \u003C\u003C \"on_read_line：bytes_transferred = \" \u003C\u003C bytes_transferred \u003C\u003C std::endl;\n    std::cout \u003C\u003C \"on_read_line：收到一行 = \" \u003C\u003C line \u003C\u003C std::endl;\n}\n\nint main(int argc, char* argv[])\n{\n    \u002F\u002F 程序从 main 函数开始执行，argc\u002Fargv 用来接收命令行参数。\n    std::string port_name = \"\u002Fdev\u002Fpts\u002F3\";\n\n    if (argc >= 2)\n    {\n        port_name = argv[1];\n    }\n\n    \u002F\u002F io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n    \u002F\u002F serial_port 表示串口设备，后续读写都通过它完成。\n    boost::asio::serial_port serial(io);\n    boost::system::error_code ec;\n\n    serial.open(port_name, ec);\n    if (ec)\n    {\n        std::cout \u003C\u003C \"打开串口失败：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n        return 1;\n    }\n\n    serial.set_option(boost::asio::serial_port_base::baud_rate(115200));\n\n    boost::asio::streambuf buffer;\n\n    std::cout \u003C\u003C \"main：注册 async_read_until\" \u003C\u003C std::endl;\n\n    boost::asio::async_read_until(serial,\n                                  buffer,\n                                  '\\n',\n                                  std::bind(on_read_line,\n                                            std::placeholders::_1,\n                                            std::placeholders::_2,\n                                            &buffer));\n\n    std::cout \u003C\u003C \"main：async_read_until 已返回，准备 io.run()\" \u003C\u003C std::endl;\n\n    \u002F\u002F 启动事件循环，前面注册的异步任务会在这里被调度执行。\n    io.run();\n\n    std::cout \u003C\u003C \"main：io.run() 返回\" \u003C\u003C std::endl;\n\n    return 0;\n}\n",[28,1850,1851,1857,1863,1870,1876,1882,1888,1892,1924,1938,1959,1963,1969,1973,1998,2004,2008,2012,2023,2029,2039,2043,2065,2086,2090,2094,2114,2118,2122,2134,2138,2150,2154,2166,2170,2174,2178,2188,2192,2206,2216,2220,2228,2234,2238,2262,2270,2274,2278,2306,2310,2320,2324,2341,2345,2362,2368,2380,2394,2408,2420,2429,2434,2452,2457,2463,2475,2480,2498,2503,2512],{"__ignoreMap":26},[68,1852,1853,1855],{"class":70,"line":71},[68,1854,213],{"class":212},[68,1856,216],{"class":78},[68,1858,1859,1861],{"class":70,"line":219},[68,1860,213],{"class":212},[68,1862,224],{"class":78},[68,1864,1865,1867],{"class":70,"line":227},[68,1866,213],{"class":212},[68,1868,1869],{"class":78}," \u003Cfunctional>\n",[68,1871,1872,1874],{"class":70,"line":235},[68,1873,213],{"class":212},[68,1875,232],{"class":78},[68,1877,1878,1880],{"class":70,"line":243},[68,1879,213],{"class":212},[68,1881,1186],{"class":78},[68,1883,1884,1886],{"class":70,"line":250},[68,1885,213],{"class":212},[68,1887,240],{"class":78},[68,1889,1890],{"class":70,"line":281},[68,1891,247],{"emptyLinePlaceholder":246},[68,1893,1894,1897,1900,1902,1905,1907,1909,1911,1913,1916,1918,1921],{"class":70,"line":287},[68,1895,1896],{"class":212},"void",[68,1898,1899],{"class":74}," on_read_line",[68,1901,260],{"class":259},[68,1903,1904],{"class":212},"const",[68,1906,798],{"class":74},[68,1908,381],{"class":259},[68,1910,421],{"class":74},[68,1912,381],{"class":259},[68,1914,1915],{"class":74},"error_code",[68,1917,1555],{"class":212},[68,1919,1920],{"class":265}," ec",[68,1922,1923],{"class":259},",\n",[68,1925,1926,1929,1931,1933,1936],{"class":70,"line":294},[68,1927,1928],{"class":74},"                  std",[68,1930,381],{"class":259},[68,1932,790],{"class":212},[68,1934,1935],{"class":265}," bytes_transferred",[68,1937,1923],{"class":259},[68,1939,1940,1943,1945,1947,1949,1951,1954,1957],{"class":70,"line":312},[68,1941,1942],{"class":74},"                  boost",[68,1944,381],{"class":259},[68,1946,384],{"class":74},[68,1948,381],{"class":259},[68,1950,1800],{"class":74},[68,1952,1953],{"class":212},"*",[68,1955,1956],{"class":265}," buffer",[68,1958,332],{"class":259},[68,1960,1961],{"class":70,"line":317},[68,1962,284],{"class":259},[68,1964,1965,1967],{"class":70,"line":335},[68,1966,320],{"class":212},[68,1968,482],{"class":259},[68,1970,1971],{"class":70,"line":341},[68,1972,338],{"class":259},[68,1974,1975,1977,1979,1981,1984,1986,1988,1990,1992,1994,1996],{"class":70,"line":358},[68,1976,493],{"class":74},[68,1978,437],{"class":259},[68,1980,440],{"class":212},[68,1982,1983],{"class":78}," \"on_read_line：读取失败：\"",[68,1985,446],{"class":212},[68,1987,505],{"class":259},[68,1989,508],{"class":74},[68,1991,511],{"class":259},[68,1993,440],{"class":212},[68,1995,454],{"class":74},[68,1997,457],{"class":259},[68,1999,2000,2002],{"class":70,"line":364},[68,2001,523],{"class":212},[68,2003,309],{"class":259},[68,2005,2006],{"class":70,"line":369},[68,2007,361],{"class":259},[68,2009,2010],{"class":70,"line":375},[68,2011,247],{"emptyLinePlaceholder":246},[68,2013,2014,2016,2018,2020],{"class":70,"line":390},[68,2015,297],{"class":74},[68,2017,1547],{"class":259},[68,2019,1550],{"class":74},[68,2021,2022],{"class":259},"(buffer);\n",[68,2024,2025,2027],{"class":70,"line":396},[68,2026,297],{"class":74},[68,2028,1565],{"class":259},[68,2030,2031,2033,2035,2037],{"class":70,"line":414},[68,2032,297],{"class":74},[68,2034,381],{"class":259},[68,2036,1574],{"class":74},[68,2038,1577],{"class":259},[68,2040,2041],{"class":70,"line":427},[68,2042,247],{"emptyLinePlaceholder":246},[68,2044,2045,2047,2049,2051,2054,2056,2059,2061,2063],{"class":70,"line":432},[68,2046,297],{"class":74},[68,2048,437],{"class":259},[68,2050,440],{"class":212},[68,2052,2053],{"class":78}," \"on_read_line：bytes_transferred = \"",[68,2055,446],{"class":212},[68,2057,2058],{"class":259}," bytes_transferred ",[68,2060,440],{"class":212},[68,2062,454],{"class":74},[68,2064,457],{"class":259},[68,2066,2067,2069,2071,2073,2076,2078,2080,2082,2084],{"class":70,"line":460},[68,2068,297],{"class":74},[68,2070,437],{"class":259},[68,2072,440],{"class":212},[68,2074,2075],{"class":78}," \"on_read_line：收到一行 = \"",[68,2077,446],{"class":212},[68,2079,1618],{"class":259},[68,2081,440],{"class":212},[68,2083,454],{"class":74},[68,2085,457],{"class":259},[68,2087,2088],{"class":70,"line":465},[68,2089,943],{"class":259},[68,2091,2092],{"class":70,"line":477},[68,2093,247],{"emptyLinePlaceholder":246},[68,2095,2096,2098,2100,2102,2104,2106,2108,2110,2112],{"class":70,"line":485},[68,2097,253],{"class":212},[68,2099,256],{"class":74},[68,2101,260],{"class":259},[68,2103,253],{"class":212},[68,2105,266],{"class":265},[68,2107,269],{"class":259},[68,2109,272],{"class":212},[68,2111,275],{"class":265},[68,2113,278],{"class":259},[68,2115,2116],{"class":70,"line":490},[68,2117,284],{"class":259},[68,2119,2120],{"class":70,"line":520},[68,2121,291],{"class":290},[68,2123,2124,2126,2128,2130,2132],{"class":70,"line":531},[68,2125,297],{"class":74},[68,2127,300],{"class":259},[68,2129,303],{"class":212},[68,2131,306],{"class":78},[68,2133,309],{"class":259},[68,2135,2136],{"class":70,"line":536},[68,2137,247],{"emptyLinePlaceholder":246},[68,2139,2140,2142,2144,2146,2148],{"class":70,"line":541},[68,2141,320],{"class":212},[68,2143,323],{"class":259},[68,2145,326],{"class":212},[68,2147,329],{"class":123},[68,2149,332],{"class":259},[68,2151,2152],{"class":70,"line":576},[68,2153,338],{"class":259},[68,2155,2156,2158,2160,2162,2164],{"class":70,"line":607},[68,2157,344],{"class":259},[68,2159,303],{"class":212},[68,2161,349],{"class":259},[68,2163,352],{"class":123},[68,2165,355],{"class":259},[68,2167,2168],{"class":70,"line":634},[68,2169,361],{"class":259},[68,2171,2172],{"class":70,"line":655},[68,2173,247],{"emptyLinePlaceholder":246},[68,2175,2176],{"class":70,"line":681},[68,2177,372],{"class":290},[68,2179,2180,2182,2184,2186],{"class":70,"line":701},[68,2181,378],{"class":74},[68,2183,381],{"class":259},[68,2185,384],{"class":74},[68,2187,387],{"class":259},[68,2189,2190],{"class":70,"line":727},[68,2191,393],{"class":290},[68,2193,2194,2196,2198,2200,2202,2204],{"class":70,"line":746},[68,2195,378],{"class":74},[68,2197,381],{"class":259},[68,2199,384],{"class":74},[68,2201,405],{"class":259},[68,2203,408],{"class":74},[68,2205,411],{"class":259},[68,2207,2208,2210,2212,2214],{"class":70,"line":751},[68,2209,378],{"class":74},[68,2211,381],{"class":259},[68,2213,421],{"class":74},[68,2215,424],{"class":259},[68,2217,2218],{"class":70,"line":772},[68,2219,247],{"emptyLinePlaceholder":246},[68,2221,2222,2224,2226],{"class":70,"line":777},[68,2223,468],{"class":259},[68,2225,471],{"class":74},[68,2227,474],{"class":259},[68,2229,2230,2232],{"class":70,"line":783},[68,2231,320],{"class":212},[68,2233,482],{"class":259},[68,2235,2236],{"class":70,"line":827},[68,2237,338],{"class":259},[68,2239,2240,2242,2244,2246,2248,2250,2252,2254,2256,2258,2260],{"class":70,"line":834},[68,2241,493],{"class":74},[68,2243,437],{"class":259},[68,2245,440],{"class":212},[68,2247,500],{"class":78},[68,2249,446],{"class":212},[68,2251,505],{"class":259},[68,2253,508],{"class":74},[68,2255,511],{"class":259},[68,2257,440],{"class":212},[68,2259,454],{"class":74},[68,2261,457],{"class":259},[68,2263,2264,2266,2268],{"class":70,"line":839},[68,2265,523],{"class":212},[68,2267,526],{"class":123},[68,2269,309],{"class":259},[68,2271,2272],{"class":70,"line":865},[68,2273,361],{"class":259},[68,2275,2276],{"class":70,"line":874},[68,2277,247],{"emptyLinePlaceholder":246},[68,2279,2280,2282,2284,2286,2288,2290,2292,2294,2296,2298,2300,2302,2304],{"class":70,"line":879},[68,2281,468],{"class":259},[68,2283,546],{"class":74},[68,2285,260],{"class":259},[68,2287,551],{"class":74},[68,2289,381],{"class":259},[68,2291,384],{"class":74},[68,2293,381],{"class":259},[68,2295,560],{"class":74},[68,2297,381],{"class":259},[68,2299,565],{"class":74},[68,2301,260],{"class":259},[68,2303,570],{"class":123},[68,2305,573],{"class":259},[68,2307,2308],{"class":70,"line":884},[68,2309,247],{"emptyLinePlaceholder":246},[68,2311,2312,2314,2316,2318],{"class":70,"line":906},[68,2313,378],{"class":74},[68,2315,381],{"class":259},[68,2317,384],{"class":74},[68,2319,1428],{"class":259},[68,2321,2322],{"class":70,"line":924},[68,2323,247],{"emptyLinePlaceholder":246},[68,2325,2326,2328,2330,2332,2335,2337,2339],{"class":70,"line":929},[68,2327,297],{"class":74},[68,2329,437],{"class":259},[68,2331,440],{"class":212},[68,2333,2334],{"class":78}," \"main：注册 async_read_until\"",[68,2336,446],{"class":212},[68,2338,454],{"class":74},[68,2340,457],{"class":259},[68,2342,2343],{"class":70,"line":940},[68,2344,247],{"emptyLinePlaceholder":246},[68,2346,2348,2350,2352,2354,2356,2359],{"class":70,"line":2347},55,[68,2349,378],{"class":74},[68,2351,381],{"class":259},[68,2353,384],{"class":74},[68,2355,381],{"class":259},[68,2357,2358],{"class":74},"async_read_until",[68,2360,2361],{"class":259},"(serial,\n",[68,2363,2365],{"class":70,"line":2364},56,[68,2366,2367],{"class":259},"                                  buffer,\n",[68,2369,2371,2374,2376,2378],{"class":70,"line":2370},57,[68,2372,2373],{"class":78},"                                  '",[68,2375,764],{"class":123},[68,2377,1482],{"class":78},[68,2379,1923],{"class":259},[68,2381,2383,2386,2388,2391],{"class":70,"line":2382},58,[68,2384,2385],{"class":74},"                                  std",[68,2387,381],{"class":259},[68,2389,2390],{"class":74},"bind",[68,2392,2393],{"class":259},"(on_read_line,\n",[68,2395,2397,2400,2402,2405],{"class":70,"line":2396},59,[68,2398,2399],{"class":74},"                                            std",[68,2401,381],{"class":259},[68,2403,2404],{"class":74},"placeholders",[68,2406,2407],{"class":259},"::_1,\n",[68,2409,2411,2413,2415,2417],{"class":70,"line":2410},60,[68,2412,2399],{"class":74},[68,2414,381],{"class":259},[68,2416,2404],{"class":74},[68,2418,2419],{"class":259},"::_2,\n",[68,2421,2423,2426],{"class":70,"line":2422},61,[68,2424,2425],{"class":212},"                                            &",[68,2427,2428],{"class":259},"buffer));\n",[68,2430,2432],{"class":70,"line":2431},62,[68,2433,247],{"emptyLinePlaceholder":246},[68,2435,2437,2439,2441,2443,2446,2448,2450],{"class":70,"line":2436},63,[68,2438,297],{"class":74},[68,2440,437],{"class":259},[68,2442,440],{"class":212},[68,2444,2445],{"class":78}," \"main：async_read_until 已返回，准备 io.run()\"",[68,2447,446],{"class":212},[68,2449,454],{"class":74},[68,2451,457],{"class":259},[68,2453,2455],{"class":70,"line":2454},64,[68,2456,247],{"emptyLinePlaceholder":246},[68,2458,2460],{"class":70,"line":2459},65,[68,2461,2462],{"class":290},"    \u002F\u002F 启动事件循环，前面注册的异步任务会在这里被调度执行。\n",[68,2464,2466,2469,2472],{"class":70,"line":2465},66,[68,2467,2468],{"class":259},"    io.",[68,2470,2471],{"class":74},"run",[68,2473,2474],{"class":259},"();\n",[68,2476,2478],{"class":70,"line":2477},67,[68,2479,247],{"emptyLinePlaceholder":246},[68,2481,2483,2485,2487,2489,2492,2494,2496],{"class":70,"line":2482},68,[68,2484,297],{"class":74},[68,2486,437],{"class":259},[68,2488,440],{"class":212},[68,2490,2491],{"class":78}," \"main：io.run() 返回\"",[68,2493,446],{"class":212},[68,2495,454],{"class":74},[68,2497,457],{"class":259},[68,2499,2501],{"class":70,"line":2500},69,[68,2502,247],{"emptyLinePlaceholder":246},[68,2504,2506,2508,2510],{"class":70,"line":2505},70,[68,2507,932],{"class":212},[68,2509,935],{"class":123},[68,2511,309],{"class":259},[68,2513,2515],{"class":70,"line":2514},71,[68,2516,943],{"class":259},[13,2518,2519,950],{},[947,2520,949],{},[53,2522,954],{"id":2523},"compile-and-run-2",[13,2525,957],{},[20,2527,2528],{"className":62,"code":114,"language":64,"meta":26,"style":26},[28,2529,2530],{"__ignoreMap":26},[68,2531,2532,2534,2536,2538,2540,2542,2544],{"class":70,"line":71},[68,2533,50],{"class":74},[68,2535,124],{"class":123},[68,2537,124],{"class":123},[68,2539,129],{"class":78},[68,2541,132],{"class":123},[68,2543,129],{"class":78},[68,2545,137],{"class":123},[13,2547,1672],{},[20,2549,2551],{"className":62,"code":2550,"language":64,"meta":26,"style":26},"g++ demo3_async_serial_read.cpp -o demo3_async_serial_read -std=c++17 -lboost_system -pthread\n.\u002Fdemo3_async_serial_read \u002Fdev\u002Fpts\u002F3\n",[28,2552,2553,2571],{"__ignoreMap":26},[68,2554,2555,2557,2560,2562,2565,2567,2569],{"class":70,"line":71},[68,2556,1006],{"class":74},[68,2558,2559],{"class":78}," demo3_async_serial_read.cpp",[68,2561,1012],{"class":123},[68,2563,2564],{"class":78}," demo3_async_serial_read",[68,2566,1018],{"class":123},[68,2568,1021],{"class":123},[68,2570,1024],{"class":123},[68,2572,2573,2576],{"class":70,"line":219},[68,2574,2575],{"class":74},".\u002Fdemo3_async_serial_read",[68,2577,1032],{"class":78},[13,2579,2580],{},"Terminal 3: Send data.",[20,2582,2584],{"className":62,"code":2583,"language":64,"meta":26,"style":26},"echo \"encoder 123\" > \u002Fdev\u002Fpts\u002F4\n",[28,2585,2586],{"__ignoreMap":26},[68,2587,2588,2590,2593,2595],{"class":70,"line":71},[68,2589,1715],{"class":123},[68,2591,2592],{"class":78}," \"encoder 123\"",[68,2594,1721],{"class":212},[68,2596,993],{"class":78},[53,2598,1036],{"id":2599},"execution-output-and-chronological-order-2",[13,2601,2602],{},"The program immediately outputs:",[20,2604,2607],{"className":2605,"code":2606,"language":25,"meta":26},[23],"main：注册 async_read_until\nmain：async_read_until 已返回，准备 io.run()\n",[28,2608,2606],{"__ignoreMap":26},[13,2610,2611,2612,2614],{},"Program stuck at ",[28,2613,1830],{},". After you send data, the program outputs:",[20,2616,2619],{"className":2617,"code":2618,"language":25,"meta":26},[23],"on_read_line：bytes_transferred = 12\non_read_line：收到一行 = encoder 123\nmain：io.run() 返回\n",[28,2620,2618],{"__ignoreMap":26},[13,2622,2623],{},"请提供您要翻译的简体中文 Markdown 片段。",[20,2625,2628],{"className":2626,"code":2627,"language":25,"meta":26},[23],"main：注册 async_read_until\nmain：async_read_until 已返回，准备 io.run()\non_read_line：bytes_transferred = 12\non_read_line：收到一行 = encoder 123\nmain：io.run() 返回\n",[28,2629,2627],{"__ignoreMap":26},[53,2631,1060],{"id":2632},"points-to-note-for-this-example-2",[13,2634,2635,2637],{},[28,2636,1824],{}," does not block. It only registers a read task.",[13,2639,2640],{},"If you do not call:",[20,2642,2644],{"className":203,"code":2643,"language":205,"meta":26,"style":26},"io.run();\n",[28,2645,2646],{"__ignoreMap":26},[68,2647,2648,2651,2653],{"class":70,"line":71},[68,2649,2650],{"class":259},"io.",[68,2652,2471],{"class":74},[68,2654,2474],{"class":259},[13,2656,2657],{},"The callback function will never execute.",[53,2659,2661],{"id":2660},"callback-parameter-description","Callback parameter description",[13,2663,2664,2666],{},[28,2665,1824],{},"'s callback usually receives two parameters:",[20,2668,2670],{"className":203,"code":2669,"language":205,"meta":26,"style":26},"const boost::system::error_code& ec\nstd::size_t bytes_transferred\n",[28,2671,2672,2690],{"__ignoreMap":26},[68,2673,2674,2676,2678,2680,2682,2685,2687],{"class":70,"line":71},[68,2675,1904],{"class":212},[68,2677,798],{"class":74},[68,2679,381],{"class":259},[68,2681,421],{"class":74},[68,2683,2684],{"class":259},"::error_code",[68,2686,1555],{"class":212},[68,2688,2689],{"class":259}," ec\n",[68,2691,2692,2695,2697,2699],{"class":70,"line":219},[68,2693,2694],{"class":74},"std",[68,2696,381],{"class":259},[68,2698,790],{"class":212},[68,2700,2701],{"class":259}," bytes_transferred\n",[13,2703,2704],{},"So when binding, use:",[20,2706,2708],{"className":203,"code":2707,"language":205,"meta":26,"style":26},"std::placeholders::_1\nstd::placeholders::_2\n",[28,2709,2710,2721],{"__ignoreMap":26},[68,2711,2712,2714,2716,2718],{"class":70,"line":71},[68,2713,2694],{"class":74},[68,2715,381],{"class":259},[68,2717,2404],{"class":74},[68,2719,2720],{"class":259},"::_1\n",[68,2722,2723,2725,2727,2729],{"class":70,"line":219},[68,2724,2694],{"class":74},[68,2726,381],{"class":259},[68,2728,2404],{"class":74},[68,2730,2731],{"class":259},"::_2\n",[13,2733,2734],{},"We also passed:",[20,2736,2738],{"className":203,"code":2737,"language":205,"meta":26,"style":26},"&buffer\n",[28,2739,2740],{"__ignoreMap":26},[68,2741,2742,2744],{"class":70,"line":71},[68,2743,1555],{"class":212},[68,2745,2746],{"class":259},"buffer\n",[13,2748,2749],{},"Used to retrieve the specific string in the callback.",[38,2751],{},[41,2753,2755],{"id":2754},"example-4-encapsulating-asynchronous-serial-line-reading-in-a-class","Example 4: Encapsulating Asynchronous Serial Line Reading in a Class",[53,2757,179],{"id":2758},"program-objective-3",[13,2760,2761],{},"Encapsulate asynchronous serial port reading into a class. This structure is closer to a real robot project.",[13,2763,2764],{},"The program continuously reads multiple lines of serial port data, prints each received line, and then registers for the next read.",[53,2766,200],{"id":2767},"full-code-3",[20,2769,2771],{"className":203,"code":2770,"language":205,"meta":26,"style":26},"#include \u003Cboost\u002Fasio.hpp>\n#include \u003Cboost\u002Fsystem\u002Ferror_code.hpp>\n#include \u003Cfunctional>\n#include \u003Ciostream>\n#include \u003Cistream>\n#include \u003Cstring>\n\nclass SerialLineReader\n{\npublic:\n    SerialLineReader(boost::asio::io_context& io, const std::string& port_name)\n        : serial_(io)\n    {\n        boost::system::error_code ec;\n\n        serial_.open(port_name, ec);\n        if (ec)\n        {\n            std::cout \u003C\u003C \"打开串口失败：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n            return;\n        }\n\n        serial_.set_option(boost::asio::serial_port_base::baud_rate(115200));\n        serial_.set_option(boost::asio::serial_port_base::character_size(8));\n        serial_.set_option(boost::asio::serial_port_base::parity(\n            boost::asio::serial_port_base::parity::none));\n        serial_.set_option(boost::asio::serial_port_base::stop_bits(\n            boost::asio::serial_port_base::stop_bits::one));\n        serial_.set_option(boost::asio::serial_port_base::flow_control(\n            boost::asio::serial_port_base::flow_control::none));\n\n        std::cout \u003C\u003C \"SerialLineReader：串口打开成功，开始异步读取\" \u003C\u003C std::endl;\n\n        start_read();\n    }\n\nprivate:\n    void start_read()\n    {\n        boost::asio::async_read_until(serial_,\n                                      buffer_,\n                                      '\\n',\n                                      std::bind(&SerialLineReader::on_read,\n                                                this,\n                                                std::placeholders::_1,\n                                                std::placeholders::_2));\n    }\n\n    void on_read(const boost::system::error_code& ec, std::size_t bytes_transferred)\n    {\n        if (ec)\n        {\n            std::cout \u003C\u003C \"SerialLineReader::on_read 错误：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n            return;\n        }\n\n        std::istream is(&buffer_);\n        std::string line;\n        std::getline(is, line);\n\n        std::cout \u003C\u003C \"收到串口行，bytes = \" \u003C\u003C bytes_transferred\n                  \u003C\u003C \"，内容 = \" \u003C\u003C line \u003C\u003C std::endl;\n\n        start_read();\n    }\n\nprivate:\n    \u002F\u002F serial_port 表示串口设备，后续读写都通过它完成。\n    boost::asio::serial_port serial_;\n    boost::asio::streambuf buffer_;\n};\n\nint main(int argc, char* argv[])\n{\n    \u002F\u002F 程序从 main 函数开始执行，argc\u002Fargv 用来接收命令行参数。\n    std::string port_name = \"\u002Fdev\u002Fpts\u002F3\";\n\n    if (argc >= 2)\n    {\n        port_name = argv[1];\n    }\n\n    \u002F\u002F io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n    SerialLineReader reader(io, port_name);\n\n    std::cout \u003C\u003C \"main：调用 io.run()，按 Ctrl+C 退出\" \u003C\u003C std::endl;\n\n    \u002F\u002F 启动事件循环，前面注册的异步任务会在这里被调度执行。\n    io.run();\n\n    std::cout \u003C\u003C \"main：io.run() 返回\" \u003C\u003C std::endl;\n\n    return 0;\n}\n",[28,2772,2773,2779,2785,2791,2797,2803,2809,2813,2821,2825,2830,2871,2882,2886,2896,2900,2909,2916,2921,2946,2953,2958,2962,2990,3018,3042,3061,3085,3103,3127,3145,3149,3166,3170,3177,3181,3185,3190,3201,3205,3220,3225,3236,3255,3262,3273,3284,3288,3292,3329,3333,3339,3343,3368,3374,3378,3382,3397,3403,3413,3417,3432,3450,3454,3460,3464,3468,3472,3476,3487,3498,3503,3508,3529,3534,3539,3552,3557,3570,3575,3588,3593,3598,3603,3614,3626,3631,3649,3654,3659,3668,3673,3690,3695,3704],{"__ignoreMap":26},[68,2774,2775,2777],{"class":70,"line":71},[68,2776,213],{"class":212},[68,2778,216],{"class":78},[68,2780,2781,2783],{"class":70,"line":219},[68,2782,213],{"class":212},[68,2784,224],{"class":78},[68,2786,2787,2789],{"class":70,"line":227},[68,2788,213],{"class":212},[68,2790,1869],{"class":78},[68,2792,2793,2795],{"class":70,"line":235},[68,2794,213],{"class":212},[68,2796,232],{"class":78},[68,2798,2799,2801],{"class":70,"line":243},[68,2800,213],{"class":212},[68,2802,1186],{"class":78},[68,2804,2805,2807],{"class":70,"line":250},[68,2806,213],{"class":212},[68,2808,240],{"class":78},[68,2810,2811],{"class":70,"line":281},[68,2812,247],{"emptyLinePlaceholder":246},[68,2814,2815,2818],{"class":70,"line":287},[68,2816,2817],{"class":212},"class",[68,2819,2820],{"class":74}," SerialLineReader\n",[68,2822,2823],{"class":70,"line":294},[68,2824,284],{"class":259},[68,2826,2827],{"class":70,"line":312},[68,2828,2829],{"class":212},"public:\n",[68,2831,2832,2835,2837,2839,2841,2843,2845,2848,2850,2853,2855,2857,2859,2861,2864,2866,2869],{"class":70,"line":317},[68,2833,2834],{"class":74},"    SerialLineReader",[68,2836,260],{"class":259},[68,2838,551],{"class":74},[68,2840,381],{"class":259},[68,2842,384],{"class":74},[68,2844,381],{"class":259},[68,2846,2847],{"class":74},"io_context",[68,2849,1555],{"class":212},[68,2851,2852],{"class":265}," io",[68,2854,269],{"class":259},[68,2856,1904],{"class":212},[68,2858,454],{"class":74},[68,2860,381],{"class":259},[68,2862,2863],{"class":74},"string",[68,2865,1555],{"class":212},[68,2867,2868],{"class":265}," port_name",[68,2870,332],{"class":259},[68,2872,2873,2876,2879],{"class":70,"line":335},[68,2874,2875],{"class":259},"        : ",[68,2877,2878],{"class":74},"serial_",[68,2880,2881],{"class":259},"(io)\n",[68,2883,2884],{"class":70,"line":341},[68,2885,338],{"class":259},[68,2887,2888,2890,2892,2894],{"class":70,"line":358},[68,2889,637],{"class":74},[68,2891,381],{"class":259},[68,2893,421],{"class":74},[68,2895,424],{"class":259},[68,2897,2898],{"class":70,"line":364},[68,2899,247],{"emptyLinePlaceholder":246},[68,2901,2902,2905,2907],{"class":70,"line":369},[68,2903,2904],{"class":259},"        serial_.",[68,2906,471],{"class":74},[68,2908,474],{"class":259},[68,2910,2911,2914],{"class":70,"line":375},[68,2912,2913],{"class":212},"        if",[68,2915,482],{"class":259},[68,2917,2918],{"class":70,"line":390},[68,2919,2920],{"class":259},"        {\n",[68,2922,2923,2926,2928,2930,2932,2934,2936,2938,2940,2942,2944],{"class":70,"line":396},[68,2924,2925],{"class":74},"            std",[68,2927,437],{"class":259},[68,2929,440],{"class":212},[68,2931,500],{"class":78},[68,2933,446],{"class":212},[68,2935,505],{"class":259},[68,2937,508],{"class":74},[68,2939,511],{"class":259},[68,2941,440],{"class":212},[68,2943,454],{"class":74},[68,2945,457],{"class":259},[68,2947,2948,2951],{"class":70,"line":414},[68,2949,2950],{"class":212},"            return",[68,2952,309],{"class":259},[68,2954,2955],{"class":70,"line":427},[68,2956,2957],{"class":259},"        }\n",[68,2959,2960],{"class":70,"line":432},[68,2961,247],{"emptyLinePlaceholder":246},[68,2963,2964,2966,2968,2970,2972,2974,2976,2978,2980,2982,2984,2986,2988],{"class":70,"line":460},[68,2965,2904],{"class":259},[68,2967,546],{"class":74},[68,2969,260],{"class":259},[68,2971,551],{"class":74},[68,2973,381],{"class":259},[68,2975,384],{"class":74},[68,2977,381],{"class":259},[68,2979,560],{"class":74},[68,2981,381],{"class":259},[68,2983,565],{"class":74},[68,2985,260],{"class":259},[68,2987,570],{"class":123},[68,2989,573],{"class":259},[68,2991,2992,2994,2996,2998,3000,3002,3004,3006,3008,3010,3012,3014,3016],{"class":70,"line":465},[68,2993,2904],{"class":259},[68,2995,546],{"class":74},[68,2997,260],{"class":259},[68,2999,551],{"class":74},[68,3001,381],{"class":259},[68,3003,384],{"class":74},[68,3005,381],{"class":259},[68,3007,560],{"class":74},[68,3009,381],{"class":259},[68,3011,597],{"class":74},[68,3013,260],{"class":259},[68,3015,602],{"class":123},[68,3017,573],{"class":259},[68,3019,3020,3022,3024,3026,3028,3030,3032,3034,3036,3038,3040],{"class":70,"line":477},[68,3021,2904],{"class":259},[68,3023,546],{"class":74},[68,3025,260],{"class":259},[68,3027,551],{"class":74},[68,3029,381],{"class":259},[68,3031,384],{"class":74},[68,3033,381],{"class":259},[68,3035,560],{"class":74},[68,3037,381],{"class":259},[68,3039,628],{"class":74},[68,3041,631],{"class":259},[68,3043,3044,3047,3049,3051,3053,3055,3057,3059],{"class":70,"line":485},[68,3045,3046],{"class":74},"            boost",[68,3048,381],{"class":259},[68,3050,384],{"class":74},[68,3052,381],{"class":259},[68,3054,560],{"class":74},[68,3056,381],{"class":259},[68,3058,628],{"class":74},[68,3060,652],{"class":259},[68,3062,3063,3065,3067,3069,3071,3073,3075,3077,3079,3081,3083],{"class":70,"line":490},[68,3064,2904],{"class":259},[68,3066,546],{"class":74},[68,3068,260],{"class":259},[68,3070,551],{"class":74},[68,3072,381],{"class":259},[68,3074,384],{"class":74},[68,3076,381],{"class":259},[68,3078,560],{"class":74},[68,3080,381],{"class":259},[68,3082,676],{"class":74},[68,3084,631],{"class":259},[68,3086,3087,3089,3091,3093,3095,3097,3099,3101],{"class":70,"line":520},[68,3088,3046],{"class":74},[68,3090,381],{"class":259},[68,3092,384],{"class":74},[68,3094,381],{"class":259},[68,3096,560],{"class":74},[68,3098,381],{"class":259},[68,3100,676],{"class":74},[68,3102,698],{"class":259},[68,3104,3105,3107,3109,3111,3113,3115,3117,3119,3121,3123,3125],{"class":70,"line":531},[68,3106,2904],{"class":259},[68,3108,546],{"class":74},[68,3110,260],{"class":259},[68,3112,551],{"class":74},[68,3114,381],{"class":259},[68,3116,384],{"class":74},[68,3118,381],{"class":259},[68,3120,560],{"class":74},[68,3122,381],{"class":259},[68,3124,722],{"class":74},[68,3126,631],{"class":259},[68,3128,3129,3131,3133,3135,3137,3139,3141,3143],{"class":70,"line":536},[68,3130,3046],{"class":74},[68,3132,381],{"class":259},[68,3134,384],{"class":74},[68,3136,381],{"class":259},[68,3138,560],{"class":74},[68,3140,381],{"class":259},[68,3142,722],{"class":74},[68,3144,652],{"class":259},[68,3146,3147],{"class":70,"line":541},[68,3148,247],{"emptyLinePlaceholder":246},[68,3150,3151,3153,3155,3157,3160,3162,3164],{"class":70,"line":576},[68,3152,493],{"class":74},[68,3154,437],{"class":259},[68,3156,440],{"class":212},[68,3158,3159],{"class":78}," \"SerialLineReader：串口打开成功，开始异步读取\"",[68,3161,446],{"class":212},[68,3163,454],{"class":74},[68,3165,457],{"class":259},[68,3167,3168],{"class":70,"line":607},[68,3169,247],{"emptyLinePlaceholder":246},[68,3171,3172,3175],{"class":70,"line":634},[68,3173,3174],{"class":74},"        start_read",[68,3176,2474],{"class":259},[68,3178,3179],{"class":70,"line":655},[68,3180,361],{"class":259},[68,3182,3183],{"class":70,"line":681},[68,3184,247],{"emptyLinePlaceholder":246},[68,3186,3187],{"class":70,"line":701},[68,3188,3189],{"class":212},"private:\n",[68,3191,3192,3195,3198],{"class":70,"line":727},[68,3193,3194],{"class":212},"    void",[68,3196,3197],{"class":74}," start_read",[68,3199,3200],{"class":259},"()\n",[68,3202,3203],{"class":70,"line":746},[68,3204,338],{"class":259},[68,3206,3207,3209,3211,3213,3215,3217],{"class":70,"line":751},[68,3208,637],{"class":74},[68,3210,381],{"class":259},[68,3212,384],{"class":74},[68,3214,381],{"class":259},[68,3216,2358],{"class":74},[68,3218,3219],{"class":259},"(serial_,\n",[68,3221,3222],{"class":70,"line":772},[68,3223,3224],{"class":259},"                                      buffer_,\n",[68,3226,3227,3230,3232,3234],{"class":70,"line":777},[68,3228,3229],{"class":78},"                                      '",[68,3231,764],{"class":123},[68,3233,1482],{"class":78},[68,3235,1923],{"class":259},[68,3237,3238,3241,3243,3245,3247,3249,3252],{"class":70,"line":783},[68,3239,3240],{"class":74},"                                      std",[68,3242,381],{"class":259},[68,3244,2390],{"class":74},[68,3246,260],{"class":259},[68,3248,1555],{"class":212},[68,3250,3251],{"class":74},"SerialLineReader",[68,3253,3254],{"class":259},"::on_read,\n",[68,3256,3257,3260],{"class":70,"line":827},[68,3258,3259],{"class":123},"                                                this",[68,3261,1923],{"class":259},[68,3263,3264,3267,3269,3271],{"class":70,"line":834},[68,3265,3266],{"class":74},"                                                std",[68,3268,381],{"class":259},[68,3270,2404],{"class":74},[68,3272,2407],{"class":259},[68,3274,3275,3277,3279,3281],{"class":70,"line":839},[68,3276,3266],{"class":74},[68,3278,381],{"class":259},[68,3280,2404],{"class":74},[68,3282,3283],{"class":259},"::_2));\n",[68,3285,3286],{"class":70,"line":865},[68,3287,361],{"class":259},[68,3289,3290],{"class":70,"line":874},[68,3291,247],{"emptyLinePlaceholder":246},[68,3293,3294,3296,3299,3301,3303,3305,3307,3309,3311,3313,3315,3317,3319,3321,3323,3325,3327],{"class":70,"line":879},[68,3295,3194],{"class":212},[68,3297,3298],{"class":74}," on_read",[68,3300,260],{"class":259},[68,3302,1904],{"class":212},[68,3304,798],{"class":74},[68,3306,381],{"class":259},[68,3308,421],{"class":74},[68,3310,381],{"class":259},[68,3312,1915],{"class":74},[68,3314,1555],{"class":212},[68,3316,1920],{"class":265},[68,3318,269],{"class":259},[68,3320,2694],{"class":74},[68,3322,381],{"class":259},[68,3324,790],{"class":212},[68,3326,1935],{"class":265},[68,3328,332],{"class":259},[68,3330,3331],{"class":70,"line":884},[68,3332,338],{"class":259},[68,3334,3335,3337],{"class":70,"line":906},[68,3336,2913],{"class":212},[68,3338,482],{"class":259},[68,3340,3341],{"class":70,"line":924},[68,3342,2920],{"class":259},[68,3344,3345,3347,3349,3351,3354,3356,3358,3360,3362,3364,3366],{"class":70,"line":929},[68,3346,2925],{"class":74},[68,3348,437],{"class":259},[68,3350,440],{"class":212},[68,3352,3353],{"class":78}," \"SerialLineReader::on_read 错误：\"",[68,3355,446],{"class":212},[68,3357,505],{"class":259},[68,3359,508],{"class":74},[68,3361,511],{"class":259},[68,3363,440],{"class":212},[68,3365,454],{"class":74},[68,3367,457],{"class":259},[68,3369,3370,3372],{"class":70,"line":940},[68,3371,2950],{"class":212},[68,3373,309],{"class":259},[68,3375,3376],{"class":70,"line":2347},[68,3377,2957],{"class":259},[68,3379,3380],{"class":70,"line":2364},[68,3381,247],{"emptyLinePlaceholder":246},[68,3383,3384,3386,3388,3390,3392,3394],{"class":70,"line":2370},[68,3385,493],{"class":74},[68,3387,1547],{"class":259},[68,3389,1550],{"class":74},[68,3391,260],{"class":259},[68,3393,1555],{"class":212},[68,3395,3396],{"class":259},"buffer_);\n",[68,3398,3399,3401],{"class":70,"line":2382},[68,3400,493],{"class":74},[68,3402,1565],{"class":259},[68,3404,3405,3407,3409,3411],{"class":70,"line":2396},[68,3406,493],{"class":74},[68,3408,381],{"class":259},[68,3410,1574],{"class":74},[68,3412,1577],{"class":259},[68,3414,3415],{"class":70,"line":2410},[68,3416,247],{"emptyLinePlaceholder":246},[68,3418,3419,3421,3423,3425,3428,3430],{"class":70,"line":2422},[68,3420,493],{"class":74},[68,3422,437],{"class":259},[68,3424,440],{"class":212},[68,3426,3427],{"class":78}," \"收到串口行，bytes = \"",[68,3429,446],{"class":212},[68,3431,2701],{"class":259},[68,3433,3434,3437,3440,3442,3444,3446,3448],{"class":70,"line":2431},[68,3435,3436],{"class":212},"                  \u003C\u003C",[68,3438,3439],{"class":78}," \"，内容 = \"",[68,3441,446],{"class":212},[68,3443,1618],{"class":259},[68,3445,440],{"class":212},[68,3447,454],{"class":74},[68,3449,457],{"class":259},[68,3451,3452],{"class":70,"line":2436},[68,3453,247],{"emptyLinePlaceholder":246},[68,3455,3456,3458],{"class":70,"line":2454},[68,3457,3174],{"class":74},[68,3459,2474],{"class":259},[68,3461,3462],{"class":70,"line":2459},[68,3463,361],{"class":259},[68,3465,3466],{"class":70,"line":2465},[68,3467,247],{"emptyLinePlaceholder":246},[68,3469,3470],{"class":70,"line":2477},[68,3471,3189],{"class":212},[68,3473,3474],{"class":70,"line":2482},[68,3475,393],{"class":290},[68,3477,3478,3480,3482,3484],{"class":70,"line":2500},[68,3479,378],{"class":74},[68,3481,381],{"class":259},[68,3483,384],{"class":74},[68,3485,3486],{"class":259},"::serial_port serial_;\n",[68,3488,3489,3491,3493,3495],{"class":70,"line":2505},[68,3490,378],{"class":74},[68,3492,381],{"class":259},[68,3494,384],{"class":74},[68,3496,3497],{"class":259},"::streambuf buffer_;\n",[68,3499,3500],{"class":70,"line":2514},[68,3501,3502],{"class":259},"};\n",[68,3504,3506],{"class":70,"line":3505},72,[68,3507,247],{"emptyLinePlaceholder":246},[68,3509,3511,3513,3515,3517,3519,3521,3523,3525,3527],{"class":70,"line":3510},73,[68,3512,253],{"class":212},[68,3514,256],{"class":74},[68,3516,260],{"class":259},[68,3518,253],{"class":212},[68,3520,266],{"class":265},[68,3522,269],{"class":259},[68,3524,272],{"class":212},[68,3526,275],{"class":265},[68,3528,278],{"class":259},[68,3530,3532],{"class":70,"line":3531},74,[68,3533,284],{"class":259},[68,3535,3537],{"class":70,"line":3536},75,[68,3538,291],{"class":290},[68,3540,3542,3544,3546,3548,3550],{"class":70,"line":3541},76,[68,3543,297],{"class":74},[68,3545,300],{"class":259},[68,3547,303],{"class":212},[68,3549,306],{"class":78},[68,3551,309],{"class":259},[68,3553,3555],{"class":70,"line":3554},77,[68,3556,247],{"emptyLinePlaceholder":246},[68,3558,3560,3562,3564,3566,3568],{"class":70,"line":3559},78,[68,3561,320],{"class":212},[68,3563,323],{"class":259},[68,3565,326],{"class":212},[68,3567,329],{"class":123},[68,3569,332],{"class":259},[68,3571,3573],{"class":70,"line":3572},79,[68,3574,338],{"class":259},[68,3576,3578,3580,3582,3584,3586],{"class":70,"line":3577},80,[68,3579,344],{"class":259},[68,3581,303],{"class":212},[68,3583,349],{"class":259},[68,3585,352],{"class":123},[68,3587,355],{"class":259},[68,3589,3591],{"class":70,"line":3590},81,[68,3592,361],{"class":259},[68,3594,3596],{"class":70,"line":3595},82,[68,3597,247],{"emptyLinePlaceholder":246},[68,3599,3601],{"class":70,"line":3600},83,[68,3602,372],{"class":290},[68,3604,3606,3608,3610,3612],{"class":70,"line":3605},84,[68,3607,378],{"class":74},[68,3609,381],{"class":259},[68,3611,384],{"class":74},[68,3613,387],{"class":259},[68,3615,3617,3620,3623],{"class":70,"line":3616},85,[68,3618,3619],{"class":259},"    SerialLineReader ",[68,3621,3622],{"class":74},"reader",[68,3624,3625],{"class":259},"(io, port_name);\n",[68,3627,3629],{"class":70,"line":3628},86,[68,3630,247],{"emptyLinePlaceholder":246},[68,3632,3634,3636,3638,3640,3643,3645,3647],{"class":70,"line":3633},87,[68,3635,297],{"class":74},[68,3637,437],{"class":259},[68,3639,440],{"class":212},[68,3641,3642],{"class":78}," \"main：调用 io.run()，按 Ctrl+C 退出\"",[68,3644,446],{"class":212},[68,3646,454],{"class":74},[68,3648,457],{"class":259},[68,3650,3652],{"class":70,"line":3651},88,[68,3653,247],{"emptyLinePlaceholder":246},[68,3655,3657],{"class":70,"line":3656},89,[68,3658,2462],{"class":290},[68,3660,3662,3664,3666],{"class":70,"line":3661},90,[68,3663,2468],{"class":259},[68,3665,2471],{"class":74},[68,3667,2474],{"class":259},[68,3669,3671],{"class":70,"line":3670},91,[68,3672,247],{"emptyLinePlaceholder":246},[68,3674,3676,3678,3680,3682,3684,3686,3688],{"class":70,"line":3675},92,[68,3677,297],{"class":74},[68,3679,437],{"class":259},[68,3681,440],{"class":212},[68,3683,2491],{"class":78},[68,3685,446],{"class":212},[68,3687,454],{"class":74},[68,3689,457],{"class":259},[68,3691,3693],{"class":70,"line":3692},93,[68,3694,247],{"emptyLinePlaceholder":246},[68,3696,3698,3700,3702],{"class":70,"line":3697},94,[68,3699,932],{"class":212},[68,3701,935],{"class":123},[68,3703,309],{"class":259},[68,3705,3707],{"class":70,"line":3706},95,[68,3708,943],{"class":259},[13,3710,3711,950],{},[947,3712,949],{},[53,3714,954],{"id":3715},"compile-and-run-3",[13,3717,957],{},[20,3719,3720],{"className":62,"code":114,"language":64,"meta":26,"style":26},[28,3721,3722],{"__ignoreMap":26},[68,3723,3724,3726,3728,3730,3732,3734,3736],{"class":70,"line":71},[68,3725,50],{"class":74},[68,3727,124],{"class":123},[68,3729,124],{"class":123},[68,3731,129],{"class":78},[68,3733,132],{"class":123},[68,3735,129],{"class":78},[68,3737,137],{"class":123},[13,3739,1672],{},[20,3741,3743],{"className":62,"code":3742,"language":64,"meta":26,"style":26},"g++ demo4_serial_class_reader.cpp -o demo4_serial_class_reader -std=c++17 -lboost_system -pthread\n.\u002Fdemo4_serial_class_reader \u002Fdev\u002Fpts\u002F3\n",[28,3744,3745,3763],{"__ignoreMap":26},[68,3746,3747,3749,3752,3754,3757,3759,3761],{"class":70,"line":71},[68,3748,1006],{"class":74},[68,3750,3751],{"class":78}," demo4_serial_class_reader.cpp",[68,3753,1012],{"class":123},[68,3755,3756],{"class":78}," demo4_serial_class_reader",[68,3758,1018],{"class":123},[68,3760,1021],{"class":123},[68,3762,1024],{"class":123},[68,3764,3765,3768],{"class":70,"line":219},[68,3766,3767],{"class":74},".\u002Fdemo4_serial_class_reader",[68,3769,1032],{"class":78},[13,3771,3772],{},"Terminal 3: Continuous data transmission.",[20,3774,3776],{"className":62,"code":3775,"language":64,"meta":26,"style":26},"echo \"imu 1 2 3\" > \u002Fdev\u002Fpts\u002F4\necho \"odom 0.1 0.2\" > \u002Fdev\u002Fpts\u002F4\necho \"battery 24.1\" > \u002Fdev\u002Fpts\u002F4\n",[28,3777,3778,3789,3800],{"__ignoreMap":26},[68,3779,3780,3782,3785,3787],{"class":70,"line":71},[68,3781,1715],{"class":123},[68,3783,3784],{"class":78}," \"imu 1 2 3\"",[68,3786,1721],{"class":212},[68,3788,993],{"class":78},[68,3790,3791,3793,3796,3798],{"class":70,"line":219},[68,3792,1715],{"class":123},[68,3794,3795],{"class":78}," \"odom 0.1 0.2\"",[68,3797,1721],{"class":212},[68,3799,993],{"class":78},[68,3801,3802,3804,3807,3809],{"class":70,"line":227},[68,3803,1715],{"class":123},[68,3805,3806],{"class":78}," \"battery 24.1\"",[68,3808,1721],{"class":212},[68,3810,993],{"class":78},[53,3812,1036],{"id":3813},"execution-output-and-chronological-order-3",[13,3815,3816],{},"After the program starts, it outputs:",[20,3818,3821],{"className":3819,"code":3820,"language":25,"meta":26},[23],"SerialLineReader：串口打开成功，开始异步读取\nmain：调用 io.run()，按 Ctrl+C 退出\n",[28,3822,3820],{"__ignoreMap":26},[13,3824,3825],{},"Each time a line is sent, the program prints a line:",[20,3827,3830],{"className":3828,"code":3829,"language":25,"meta":26},[23],"收到串口行，bytes = 10，内容 = imu 1 2 3\n收到串口行，bytes = 13，内容 = odom 0.1 0.2\n收到串口行，bytes = 13，内容 = battery 24.1\n",[28,3831,3829],{"__ignoreMap":26},[13,3833,3834,3835,3838],{},"The program will not exit automatically, because each time a line is received, it calls ",[28,3836,3837],{},"start_read()"," again.",[53,3840,1060],{"id":3841},"points-to-note-for-this-example-3",[13,3843,3844],{},"This sentence is the key to continuous reading:",[20,3846,3848],{"className":203,"code":3847,"language":205,"meta":26,"style":26},"start_read();\n",[28,3849,3850],{"__ignoreMap":26},[68,3851,3852,3855],{"class":70,"line":71},[68,3853,3854],{"class":74},"start_read",[68,3856,2474],{"class":259},[13,3858,3859,3860,3863],{},"At the end of ",[28,3861,3862],{},"on_read()",", it again registers the next asynchronous read.",[13,3865,3866,3867,3869],{},"If this line is not present, the program will only read one line, and then ",[28,3868,1830],{}," will return.",[53,3871,3873],{"id":3872},"class-member-variable-lifecycle-explanation","Class Member Variable Lifecycle Explanation",[20,3875,3877],{"className":203,"code":3876,"language":205,"meta":26,"style":26},"boost::asio::serial_port serial_;\nboost::asio::streambuf buffer_;\n",[28,3878,3879,3889],{"__ignoreMap":26},[68,3880,3881,3883,3885,3887],{"class":70,"line":71},[68,3882,551],{"class":74},[68,3884,381],{"class":259},[68,3886,384],{"class":74},[68,3888,3486],{"class":259},[68,3890,3891,3893,3895,3897],{"class":70,"line":219},[68,3892,551],{"class":74},[68,3894,381],{"class":259},[68,3896,384],{"class":74},[68,3898,3497],{"class":259},[13,3900,3901,3902,36],{},"They are class member variables with a lifetime as long as ",[28,3903,3904],{},"SerialLineReader reader",[13,3906,3907],{},"This is safer than creating a temporary buffer in a local function.",[53,3909,3911],{"id":3910},"member-function-binding-description","Member function binding description",[20,3913,3915],{"className":203,"code":3914,"language":205,"meta":26,"style":26},"std::bind(&SerialLineReader::on_read,\n          this,\n          std::placeholders::_1,\n          std::placeholders::_2)\n",[28,3916,3917,3933,3940,3951],{"__ignoreMap":26},[68,3918,3919,3921,3923,3925,3927,3929,3931],{"class":70,"line":71},[68,3920,2694],{"class":74},[68,3922,381],{"class":259},[68,3924,2390],{"class":74},[68,3926,260],{"class":259},[68,3928,1555],{"class":212},[68,3930,3251],{"class":74},[68,3932,3254],{"class":259},[68,3934,3935,3938],{"class":70,"line":219},[68,3936,3937],{"class":123},"          this",[68,3939,1923],{"class":259},[68,3941,3942,3945,3947,3949],{"class":70,"line":227},[68,3943,3944],{"class":74},"          std",[68,3946,381],{"class":259},[68,3948,2404],{"class":74},[68,3950,2407],{"class":259},[68,3952,3953,3955,3957,3959],{"class":70,"line":235},[68,3954,3944],{"class":74},[68,3956,381],{"class":259},[68,3958,2404],{"class":74},[68,3960,3961],{"class":259},"::_2)\n",[13,3963,3964],{},"Called after the asynchronous read is complete:",[20,3966,3968],{"className":203,"code":3967,"language":205,"meta":26,"style":26},"this->on_read(ec, bytes_transferred);\n",[28,3969,3970],{"__ignoreMap":26},[68,3971,3972,3975,3978,3981],{"class":70,"line":71},[68,3973,3974],{"class":123},"this",[68,3976,3977],{"class":259},"->",[68,3979,3980],{"class":74},"on_read",[68,3982,3983],{"class":259},"(ec, bytes_transferred);\n",[38,3985],{},[41,3987,3989],{"id":3988},"example-5-encapsulating-asynchronous-serial-port-write-queue-in-a-class","Example 5: Encapsulating Asynchronous Serial Port Write Queue in a Class",[53,3991,179],{"id":3992},"program-objective-4",[13,3994,3995],{},"A real robot's host computer often needs to continuously send commands to the lower computer, for example:",[20,3997,4000],{"className":3998,"code":3999,"language":25,"meta":26},[23],"cmd_vel 0.2 0.0\ncmd_vel 0.2 0.1\ncmd_vel 0.0 0.0\n",[28,4001,3999],{"__ignoreMap":26},[13,4003,4004,4005,4008],{},"When writing asynchronously, you cannot casually have multiple ",[28,4006,4007],{},"async_write()"," writing to the same serial port simultaneously. A more stable approach is to use a write queue:",[20,4010,4013],{"className":4011,"code":4012,"language":25,"meta":26},[23],"如果当前没有写操作，就开始写\n如果正在写，就先放入队列\n当前写完后，再写下一条\n",[28,4014,4012],{"__ignoreMap":26},[53,4016,200],{"id":4017},"full-code-4",[20,4019,4021],{"className":203,"code":4020,"language":205,"meta":26,"style":26},"#include \u003Cboost\u002Fasio.hpp>\n#include \u003Cboost\u002Fsystem\u002Ferror_code.hpp>\n#include \u003Cdeque>\n#include \u003Cfunctional>\n#include \u003Ciostream>\n#include \u003Cstring>\n\nclass SerialWriter\n{\npublic:\n    SerialWriter(boost::asio::io_context& io, const std::string& port_name)\n        : serial_(io)\n    {\n        boost::system::error_code ec;\n        serial_.open(port_name, ec);\n        if (ec)\n        {\n            std::cout \u003C\u003C \"打开串口失败：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n            return;\n        }\n\n        serial_.set_option(boost::asio::serial_port_base::baud_rate(115200));\n        std::cout \u003C\u003C \"SerialWriter：串口打开成功\" \u003C\u003C std::endl;\n    }\n\n    void async_send(const std::string& msg)\n    {\n        bool writing = !write_queue_.empty();\n\n        write_queue_.push_back(msg);\n\n        std::cout \u003C\u003C \"加入发送队列：\" \u003C\u003C msg;\n\n        if (!writing)\n        {\n            do_write();\n        }\n    }\n\nprivate:\n    void do_write()\n    {\n        \u002F\u002F 注册异步写入，写完后由回调通知结果。\n        boost::asio::async_write(serial_,\n                                 boost::asio::buffer(write_queue_.front()),\n                                 std::bind(&SerialWriter::on_write,\n                                           this,\n                                           std::placeholders::_1,\n                                           std::placeholders::_2));\n    }\n\n    void on_write(const boost::system::error_code& ec, std::size_t bytes_transferred)\n    {\n        if (ec)\n        {\n            std::cout \u003C\u003C \"发送失败：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n            return;\n        }\n\n        std::cout \u003C\u003C \"发送完成，字节数 = \" \u003C\u003C bytes_transferred \u003C\u003C std::endl;\n\n        write_queue_.pop_front();\n\n        if (!write_queue_.empty())\n        {\n            do_write();\n        }\n    }\n\nprivate:\n    boost::asio::serial_port serial_;\n    std::deque\u003Cstd::string> write_queue_;\n};\n\nint main(int argc, char* argv[])\n{\n    \u002F\u002F 程序从 main 函数开始执行，argc\u002Fargv 用来接收命令行参数。\n    std::string port_name = \"\u002Fdev\u002Fpts\u002F3\";\n\n    if (argc >= 2)\n    {\n        port_name = argv[1];\n    }\n\n    \u002F\u002F io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n    SerialWriter writer(io, port_name);\n\n    writer.async_send(\"cmd_vel 0.2 0.0\\n\");\n    writer.async_send(\"cmd_vel 0.2 0.1\\n\");\n    writer.async_send(\"cmd_vel 0.0 0.0\\n\");\n\n    \u002F\u002F 启动事件循环，前面注册的异步任务会在这里被调度执行。\n    io.run();\n\n    std::cout \u003C\u003C \"main：发送队列清空，程序结束\" \u003C\u003C std::endl;\n\n    return 0;\n}\n",[28,4022,4023,4029,4035,4042,4048,4054,4060,4064,4071,4075,4079,4116,4124,4128,4138,4146,4152,4156,4180,4186,4190,4194,4222,4239,4243,4247,4271,4275,4296,4300,4311,4315,4331,4335,4348,4352,4359,4363,4367,4371,4375,4384,4388,4393,4408,4430,4449,4456,4467,4477,4481,4485,4522,4526,4532,4536,4560,4566,4570,4574,4595,4599,4608,4612,4627,4631,4637,4641,4645,4649,4653,4663,4684,4688,4692,4712,4716,4720,4732,4736,4748,4752,4764,4768,4772,4776,4786,4796,4800,4820,4837,4854,4858,4862,4870,4874,4892,4897,4906],{"__ignoreMap":26},[68,4024,4025,4027],{"class":70,"line":71},[68,4026,213],{"class":212},[68,4028,216],{"class":78},[68,4030,4031,4033],{"class":70,"line":219},[68,4032,213],{"class":212},[68,4034,224],{"class":78},[68,4036,4037,4039],{"class":70,"line":227},[68,4038,213],{"class":212},[68,4040,4041],{"class":78}," \u003Cdeque>\n",[68,4043,4044,4046],{"class":70,"line":235},[68,4045,213],{"class":212},[68,4047,1869],{"class":78},[68,4049,4050,4052],{"class":70,"line":243},[68,4051,213],{"class":212},[68,4053,232],{"class":78},[68,4055,4056,4058],{"class":70,"line":250},[68,4057,213],{"class":212},[68,4059,240],{"class":78},[68,4061,4062],{"class":70,"line":281},[68,4063,247],{"emptyLinePlaceholder":246},[68,4065,4066,4068],{"class":70,"line":287},[68,4067,2817],{"class":212},[68,4069,4070],{"class":74}," SerialWriter\n",[68,4072,4073],{"class":70,"line":294},[68,4074,284],{"class":259},[68,4076,4077],{"class":70,"line":312},[68,4078,2829],{"class":212},[68,4080,4081,4084,4086,4088,4090,4092,4094,4096,4098,4100,4102,4104,4106,4108,4110,4112,4114],{"class":70,"line":317},[68,4082,4083],{"class":74},"    SerialWriter",[68,4085,260],{"class":259},[68,4087,551],{"class":74},[68,4089,381],{"class":259},[68,4091,384],{"class":74},[68,4093,381],{"class":259},[68,4095,2847],{"class":74},[68,4097,1555],{"class":212},[68,4099,2852],{"class":265},[68,4101,269],{"class":259},[68,4103,1904],{"class":212},[68,4105,454],{"class":74},[68,4107,381],{"class":259},[68,4109,2863],{"class":74},[68,4111,1555],{"class":212},[68,4113,2868],{"class":265},[68,4115,332],{"class":259},[68,4117,4118,4120,4122],{"class":70,"line":335},[68,4119,2875],{"class":259},[68,4121,2878],{"class":74},[68,4123,2881],{"class":259},[68,4125,4126],{"class":70,"line":341},[68,4127,338],{"class":259},[68,4129,4130,4132,4134,4136],{"class":70,"line":358},[68,4131,637],{"class":74},[68,4133,381],{"class":259},[68,4135,421],{"class":74},[68,4137,424],{"class":259},[68,4139,4140,4142,4144],{"class":70,"line":364},[68,4141,2904],{"class":259},[68,4143,471],{"class":74},[68,4145,474],{"class":259},[68,4147,4148,4150],{"class":70,"line":369},[68,4149,2913],{"class":212},[68,4151,482],{"class":259},[68,4153,4154],{"class":70,"line":375},[68,4155,2920],{"class":259},[68,4157,4158,4160,4162,4164,4166,4168,4170,4172,4174,4176,4178],{"class":70,"line":390},[68,4159,2925],{"class":74},[68,4161,437],{"class":259},[68,4163,440],{"class":212},[68,4165,500],{"class":78},[68,4167,446],{"class":212},[68,4169,505],{"class":259},[68,4171,508],{"class":74},[68,4173,511],{"class":259},[68,4175,440],{"class":212},[68,4177,454],{"class":74},[68,4179,457],{"class":259},[68,4181,4182,4184],{"class":70,"line":396},[68,4183,2950],{"class":212},[68,4185,309],{"class":259},[68,4187,4188],{"class":70,"line":414},[68,4189,2957],{"class":259},[68,4191,4192],{"class":70,"line":427},[68,4193,247],{"emptyLinePlaceholder":246},[68,4195,4196,4198,4200,4202,4204,4206,4208,4210,4212,4214,4216,4218,4220],{"class":70,"line":432},[68,4197,2904],{"class":259},[68,4199,546],{"class":74},[68,4201,260],{"class":259},[68,4203,551],{"class":74},[68,4205,381],{"class":259},[68,4207,384],{"class":74},[68,4209,381],{"class":259},[68,4211,560],{"class":74},[68,4213,381],{"class":259},[68,4215,565],{"class":74},[68,4217,260],{"class":259},[68,4219,570],{"class":123},[68,4221,573],{"class":259},[68,4223,4224,4226,4228,4230,4233,4235,4237],{"class":70,"line":460},[68,4225,493],{"class":74},[68,4227,437],{"class":259},[68,4229,440],{"class":212},[68,4231,4232],{"class":78}," \"SerialWriter：串口打开成功\"",[68,4234,446],{"class":212},[68,4236,454],{"class":74},[68,4238,457],{"class":259},[68,4240,4241],{"class":70,"line":465},[68,4242,361],{"class":259},[68,4244,4245],{"class":70,"line":477},[68,4246,247],{"emptyLinePlaceholder":246},[68,4248,4249,4251,4254,4256,4258,4260,4262,4264,4266,4269],{"class":70,"line":485},[68,4250,3194],{"class":212},[68,4252,4253],{"class":74}," async_send",[68,4255,260],{"class":259},[68,4257,1904],{"class":212},[68,4259,454],{"class":74},[68,4261,381],{"class":259},[68,4263,2863],{"class":74},[68,4265,1555],{"class":212},[68,4267,4268],{"class":265}," msg",[68,4270,332],{"class":259},[68,4272,4273],{"class":70,"line":490},[68,4274,338],{"class":259},[68,4276,4277,4280,4283,4285,4288,4291,4294],{"class":70,"line":520},[68,4278,4279],{"class":212},"        bool",[68,4281,4282],{"class":259}," writing ",[68,4284,303],{"class":212},[68,4286,4287],{"class":212}," !",[68,4289,4290],{"class":259},"write_queue_.",[68,4292,4293],{"class":74},"empty",[68,4295,2474],{"class":259},[68,4297,4298],{"class":70,"line":531},[68,4299,247],{"emptyLinePlaceholder":246},[68,4301,4302,4305,4308],{"class":70,"line":536},[68,4303,4304],{"class":259},"        write_queue_.",[68,4306,4307],{"class":74},"push_back",[68,4309,4310],{"class":259},"(msg);\n",[68,4312,4313],{"class":70,"line":541},[68,4314,247],{"emptyLinePlaceholder":246},[68,4316,4317,4319,4321,4323,4326,4328],{"class":70,"line":576},[68,4318,493],{"class":74},[68,4320,437],{"class":259},[68,4322,440],{"class":212},[68,4324,4325],{"class":78}," \"加入发送队列：\"",[68,4327,446],{"class":212},[68,4329,4330],{"class":259}," msg;\n",[68,4332,4333],{"class":70,"line":607},[68,4334,247],{"emptyLinePlaceholder":246},[68,4336,4337,4339,4342,4345],{"class":70,"line":634},[68,4338,2913],{"class":212},[68,4340,4341],{"class":259}," (",[68,4343,4344],{"class":212},"!",[68,4346,4347],{"class":259},"writing)\n",[68,4349,4350],{"class":70,"line":655},[68,4351,2920],{"class":259},[68,4353,4354,4357],{"class":70,"line":681},[68,4355,4356],{"class":74},"            do_write",[68,4358,2474],{"class":259},[68,4360,4361],{"class":70,"line":701},[68,4362,2957],{"class":259},[68,4364,4365],{"class":70,"line":727},[68,4366,361],{"class":259},[68,4368,4369],{"class":70,"line":746},[68,4370,247],{"emptyLinePlaceholder":246},[68,4372,4373],{"class":70,"line":751},[68,4374,3189],{"class":212},[68,4376,4377,4379,4382],{"class":70,"line":772},[68,4378,3194],{"class":212},[68,4380,4381],{"class":74}," do_write",[68,4383,3200],{"class":259},[68,4385,4386],{"class":70,"line":777},[68,4387,338],{"class":259},[68,4389,4390],{"class":70,"line":783},[68,4391,4392],{"class":290},"        \u002F\u002F 注册异步写入，写完后由回调通知结果。\n",[68,4394,4395,4397,4399,4401,4403,4406],{"class":70,"line":827},[68,4396,637],{"class":74},[68,4398,381],{"class":259},[68,4400,384],{"class":74},[68,4402,381],{"class":259},[68,4404,4405],{"class":74},"async_write",[68,4407,3219],{"class":259},[68,4409,4410,4413,4415,4417,4419,4421,4424,4427],{"class":70,"line":834},[68,4411,4412],{"class":74},"                                 boost",[68,4414,381],{"class":259},[68,4416,384],{"class":74},[68,4418,381],{"class":259},[68,4420,821],{"class":74},[68,4422,4423],{"class":259},"(write_queue_.",[68,4425,4426],{"class":74},"front",[68,4428,4429],{"class":259},"()),\n",[68,4431,4432,4435,4437,4439,4441,4443,4446],{"class":70,"line":839},[68,4433,4434],{"class":74},"                                 std",[68,4436,381],{"class":259},[68,4438,2390],{"class":74},[68,4440,260],{"class":259},[68,4442,1555],{"class":212},[68,4444,4445],{"class":74},"SerialWriter",[68,4447,4448],{"class":259},"::on_write,\n",[68,4450,4451,4454],{"class":70,"line":865},[68,4452,4453],{"class":123},"                                           this",[68,4455,1923],{"class":259},[68,4457,4458,4461,4463,4465],{"class":70,"line":874},[68,4459,4460],{"class":74},"                                           std",[68,4462,381],{"class":259},[68,4464,2404],{"class":74},[68,4466,2407],{"class":259},[68,4468,4469,4471,4473,4475],{"class":70,"line":879},[68,4470,4460],{"class":74},[68,4472,381],{"class":259},[68,4474,2404],{"class":74},[68,4476,3283],{"class":259},[68,4478,4479],{"class":70,"line":884},[68,4480,361],{"class":259},[68,4482,4483],{"class":70,"line":906},[68,4484,247],{"emptyLinePlaceholder":246},[68,4486,4487,4489,4492,4494,4496,4498,4500,4502,4504,4506,4508,4510,4512,4514,4516,4518,4520],{"class":70,"line":924},[68,4488,3194],{"class":212},[68,4490,4491],{"class":74}," on_write",[68,4493,260],{"class":259},[68,4495,1904],{"class":212},[68,4497,798],{"class":74},[68,4499,381],{"class":259},[68,4501,421],{"class":74},[68,4503,381],{"class":259},[68,4505,1915],{"class":74},[68,4507,1555],{"class":212},[68,4509,1920],{"class":265},[68,4511,269],{"class":259},[68,4513,2694],{"class":74},[68,4515,381],{"class":259},[68,4517,790],{"class":212},[68,4519,1935],{"class":265},[68,4521,332],{"class":259},[68,4523,4524],{"class":70,"line":929},[68,4525,338],{"class":259},[68,4527,4528,4530],{"class":70,"line":940},[68,4529,2913],{"class":212},[68,4531,482],{"class":259},[68,4533,4534],{"class":70,"line":2347},[68,4535,2920],{"class":259},[68,4537,4538,4540,4542,4544,4546,4548,4550,4552,4554,4556,4558],{"class":70,"line":2364},[68,4539,2925],{"class":74},[68,4541,437],{"class":259},[68,4543,440],{"class":212},[68,4545,848],{"class":78},[68,4547,446],{"class":212},[68,4549,505],{"class":259},[68,4551,508],{"class":74},[68,4553,511],{"class":259},[68,4555,440],{"class":212},[68,4557,454],{"class":74},[68,4559,457],{"class":259},[68,4561,4562,4564],{"class":70,"line":2370},[68,4563,2950],{"class":212},[68,4565,309],{"class":259},[68,4567,4568],{"class":70,"line":2382},[68,4569,2957],{"class":259},[68,4571,4572],{"class":70,"line":2396},[68,4573,247],{"emptyLinePlaceholder":246},[68,4575,4576,4578,4580,4582,4585,4587,4589,4591,4593],{"class":70,"line":2410},[68,4577,493],{"class":74},[68,4579,437],{"class":259},[68,4581,440],{"class":212},[68,4583,4584],{"class":78}," \"发送完成，字节数 = \"",[68,4586,446],{"class":212},[68,4588,2058],{"class":259},[68,4590,440],{"class":212},[68,4592,454],{"class":74},[68,4594,457],{"class":259},[68,4596,4597],{"class":70,"line":2422},[68,4598,247],{"emptyLinePlaceholder":246},[68,4600,4601,4603,4606],{"class":70,"line":2431},[68,4602,4304],{"class":259},[68,4604,4605],{"class":74},"pop_front",[68,4607,2474],{"class":259},[68,4609,4610],{"class":70,"line":2436},[68,4611,247],{"emptyLinePlaceholder":246},[68,4613,4614,4616,4618,4620,4622,4624],{"class":70,"line":2454},[68,4615,2913],{"class":212},[68,4617,4341],{"class":259},[68,4619,4344],{"class":212},[68,4621,4290],{"class":259},[68,4623,4293],{"class":74},[68,4625,4626],{"class":259},"())\n",[68,4628,4629],{"class":70,"line":2459},[68,4630,2920],{"class":259},[68,4632,4633,4635],{"class":70,"line":2465},[68,4634,4356],{"class":74},[68,4636,2474],{"class":259},[68,4638,4639],{"class":70,"line":2477},[68,4640,2957],{"class":259},[68,4642,4643],{"class":70,"line":2482},[68,4644,361],{"class":259},[68,4646,4647],{"class":70,"line":2500},[68,4648,247],{"emptyLinePlaceholder":246},[68,4650,4651],{"class":70,"line":2505},[68,4652,3189],{"class":212},[68,4654,4655,4657,4659,4661],{"class":70,"line":2514},[68,4656,378],{"class":74},[68,4658,381],{"class":259},[68,4660,384],{"class":74},[68,4662,3486],{"class":259},[68,4664,4665,4667,4670,4673,4675,4678,4681],{"class":70,"line":3505},[68,4666,297],{"class":74},[68,4668,4669],{"class":259},"::deque",[68,4671,4672],{"class":212},"\u003C",[68,4674,2694],{"class":74},[68,4676,4677],{"class":259},"::string",[68,4679,4680],{"class":212},">",[68,4682,4683],{"class":259}," write_queue_;\n",[68,4685,4686],{"class":70,"line":3510},[68,4687,3502],{"class":259},[68,4689,4690],{"class":70,"line":3531},[68,4691,247],{"emptyLinePlaceholder":246},[68,4693,4694,4696,4698,4700,4702,4704,4706,4708,4710],{"class":70,"line":3536},[68,4695,253],{"class":212},[68,4697,256],{"class":74},[68,4699,260],{"class":259},[68,4701,253],{"class":212},[68,4703,266],{"class":265},[68,4705,269],{"class":259},[68,4707,272],{"class":212},[68,4709,275],{"class":265},[68,4711,278],{"class":259},[68,4713,4714],{"class":70,"line":3541},[68,4715,284],{"class":259},[68,4717,4718],{"class":70,"line":3554},[68,4719,291],{"class":290},[68,4721,4722,4724,4726,4728,4730],{"class":70,"line":3559},[68,4723,297],{"class":74},[68,4725,300],{"class":259},[68,4727,303],{"class":212},[68,4729,306],{"class":78},[68,4731,309],{"class":259},[68,4733,4734],{"class":70,"line":3572},[68,4735,247],{"emptyLinePlaceholder":246},[68,4737,4738,4740,4742,4744,4746],{"class":70,"line":3577},[68,4739,320],{"class":212},[68,4741,323],{"class":259},[68,4743,326],{"class":212},[68,4745,329],{"class":123},[68,4747,332],{"class":259},[68,4749,4750],{"class":70,"line":3590},[68,4751,338],{"class":259},[68,4753,4754,4756,4758,4760,4762],{"class":70,"line":3595},[68,4755,344],{"class":259},[68,4757,303],{"class":212},[68,4759,349],{"class":259},[68,4761,352],{"class":123},[68,4763,355],{"class":259},[68,4765,4766],{"class":70,"line":3600},[68,4767,361],{"class":259},[68,4769,4770],{"class":70,"line":3605},[68,4771,247],{"emptyLinePlaceholder":246},[68,4773,4774],{"class":70,"line":3616},[68,4775,372],{"class":290},[68,4777,4778,4780,4782,4784],{"class":70,"line":3628},[68,4779,378],{"class":74},[68,4781,381],{"class":259},[68,4783,384],{"class":74},[68,4785,387],{"class":259},[68,4787,4788,4791,4794],{"class":70,"line":3633},[68,4789,4790],{"class":259},"    SerialWriter ",[68,4792,4793],{"class":74},"writer",[68,4795,3625],{"class":259},[68,4797,4798],{"class":70,"line":3651},[68,4799,247],{"emptyLinePlaceholder":246},[68,4801,4802,4805,4808,4810,4813,4815,4817],{"class":70,"line":3656},[68,4803,4804],{"class":259},"    writer.",[68,4806,4807],{"class":74},"async_send",[68,4809,260],{"class":259},[68,4811,4812],{"class":78},"\"cmd_vel 0.2 0.0",[68,4814,764],{"class":123},[68,4816,767],{"class":78},[68,4818,4819],{"class":259},");\n",[68,4821,4822,4824,4826,4828,4831,4833,4835],{"class":70,"line":3661},[68,4823,4804],{"class":259},[68,4825,4807],{"class":74},[68,4827,260],{"class":259},[68,4829,4830],{"class":78},"\"cmd_vel 0.2 0.1",[68,4832,764],{"class":123},[68,4834,767],{"class":78},[68,4836,4819],{"class":259},[68,4838,4839,4841,4843,4845,4848,4850,4852],{"class":70,"line":3670},[68,4840,4804],{"class":259},[68,4842,4807],{"class":74},[68,4844,260],{"class":259},[68,4846,4847],{"class":78},"\"cmd_vel 0.0 0.0",[68,4849,764],{"class":123},[68,4851,767],{"class":78},[68,4853,4819],{"class":259},[68,4855,4856],{"class":70,"line":3675},[68,4857,247],{"emptyLinePlaceholder":246},[68,4859,4860],{"class":70,"line":3692},[68,4861,2462],{"class":290},[68,4863,4864,4866,4868],{"class":70,"line":3697},[68,4865,2468],{"class":259},[68,4867,2471],{"class":74},[68,4869,2474],{"class":259},[68,4871,4872],{"class":70,"line":3706},[68,4873,247],{"emptyLinePlaceholder":246},[68,4875,4877,4879,4881,4883,4886,4888,4890],{"class":70,"line":4876},96,[68,4878,297],{"class":74},[68,4880,437],{"class":259},[68,4882,440],{"class":212},[68,4884,4885],{"class":78}," \"main：发送队列清空，程序结束\"",[68,4887,446],{"class":212},[68,4889,454],{"class":74},[68,4891,457],{"class":259},[68,4893,4895],{"class":70,"line":4894},97,[68,4896,247],{"emptyLinePlaceholder":246},[68,4898,4900,4902,4904],{"class":70,"line":4899},98,[68,4901,932],{"class":212},[68,4903,935],{"class":123},[68,4905,309],{"class":259},[68,4907,4909],{"class":70,"line":4908},99,[68,4910,943],{"class":259},[13,4912,4913,950],{},[947,4914,949],{},[53,4916,954],{"id":4917},"compile-and-run-4",[13,4919,957],{},[20,4921,4922],{"className":62,"code":114,"language":64,"meta":26,"style":26},[28,4923,4924],{"__ignoreMap":26},[68,4925,4926,4928,4930,4932,4934,4936,4938],{"class":70,"line":71},[68,4927,50],{"class":74},[68,4929,124],{"class":123},[68,4931,124],{"class":123},[68,4933,129],{"class":78},[68,4935,132],{"class":123},[68,4937,129],{"class":78},[68,4939,137],{"class":123},[13,4941,980],{},[20,4943,4944],{"className":62,"code":983,"language":64,"meta":26,"style":26},[28,4945,4946],{"__ignoreMap":26},[68,4947,4948,4950],{"class":70,"line":71},[68,4949,990],{"class":74},[68,4951,993],{"class":78},[13,4953,4954],{},"Terminal 3: Run the program.",[20,4956,4958],{"className":62,"code":4957,"language":64,"meta":26,"style":26},"g++ demo5_serial_write_queue.cpp -o demo5_serial_write_queue -std=c++17 -lboost_system -pthread\n.\u002Fdemo5_serial_write_queue \u002Fdev\u002Fpts\u002F3\n",[28,4959,4960,4978],{"__ignoreMap":26},[68,4961,4962,4964,4967,4969,4972,4974,4976],{"class":70,"line":71},[68,4963,1006],{"class":74},[68,4965,4966],{"class":78}," demo5_serial_write_queue.cpp",[68,4968,1012],{"class":123},[68,4970,4971],{"class":78}," demo5_serial_write_queue",[68,4973,1018],{"class":123},[68,4975,1021],{"class":123},[68,4977,1024],{"class":123},[68,4979,4980,4983],{"class":70,"line":219},[68,4981,4982],{"class":74},".\u002Fdemo5_serial_write_queue",[68,4984,1032],{"class":78},[53,4986,1036],{"id":4987},"execution-output-and-chronological-order-4",[13,4989,4990],{},"The program terminal outputs something like:",[20,4992,4995],{"className":4993,"code":4994,"language":25,"meta":26},[23],"SerialWriter：串口打开成功\n加入发送队列：cmd_vel 0.2 0.0\n加入发送队列：cmd_vel 0.2 0.1\n加入发送队列：cmd_vel 0.0 0.0\n发送完成，字节数 = 16\n发送完成，字节数 = 16\n发送完成，字节数 = 16\nmain：发送队列清空，程序结束\n",[28,4996,4994],{"__ignoreMap":26},[13,4998,1048],{},[20,5000,5002],{"className":5001,"code":3999,"language":25,"meta":26},[23],[28,5003,3999],{"__ignoreMap":26},[53,5005,1060],{"id":5006},"points-to-note-for-this-example-4",[13,5008,5009,5010,5013],{},"You cannot make ",[28,5011,5012],{},"msg"," a temporary local variable and then immediately perform an asynchronous write, because the asynchronous write may not have completed before the data is destroyed.",[13,5015,5016],{},"This example uses:",[20,5018,5020],{"className":203,"code":5019,"language":205,"meta":26,"style":26},"std::deque\u003Cstd::string> write_queue_;\n",[28,5021,5022],{"__ignoreMap":26},[68,5023,5024,5026,5028,5030,5032,5034,5036],{"class":70,"line":71},[68,5025,2694],{"class":74},[68,5027,4669],{"class":259},[68,5029,4672],{"class":212},[68,5031,2694],{"class":74},[68,5033,4677],{"class":259},[68,5035,4680],{"class":212},[68,5037,4683],{"class":259},[13,5039,5040],{},"Save the pending data, ensuring that the string pointed to by buffer persists until the write is complete.",[53,5042,5044,5046],{"id":5043},"async_write-description",[28,5045,4007],{}," Description",[20,5048,5050],{"className":203,"code":5049,"language":205,"meta":26,"style":26},"boost::asio::async_write(serial_, buffer, handler);\n",[28,5051,5052],{"__ignoreMap":26},[68,5053,5054,5056,5058,5060,5062,5064],{"class":70,"line":71},[68,5055,551],{"class":74},[68,5057,381],{"class":259},[68,5059,384],{"class":74},[68,5061,381],{"class":259},[68,5063,4405],{"class":74},[68,5065,5066],{"class":259},"(serial_, buffer, handler);\n",[13,5068,5069],{},"Function: asynchronously write the entire buffer.",[13,5071,5072],{},"Callback parameter:",[20,5074,5075],{"className":203,"code":2669,"language":205,"meta":26,"style":26},[28,5076,5077,5093],{"__ignoreMap":26},[68,5078,5079,5081,5083,5085,5087,5089,5091],{"class":70,"line":71},[68,5080,1904],{"class":212},[68,5082,798],{"class":74},[68,5084,381],{"class":259},[68,5086,421],{"class":74},[68,5088,2684],{"class":259},[68,5090,1555],{"class":212},[68,5092,2689],{"class":259},[68,5094,5095,5097,5099,5101],{"class":70,"line":219},[68,5096,2694],{"class":74},[68,5098,381],{"class":259},[68,5100,790],{"class":212},[68,5102,2701],{"class":259},[13,5104,5105,5106,36],{},"Return value: ",[28,5107,1896],{},[38,5109],{},[41,5111,5113],{"id":5112},"section-summary","Section Summary",[1817,5115,5116,5119,5125,5130,5137,5140],{},[1820,5117,5118],{},"Synchronous serial port read\u002Fwrite is simple, but it will block.",[1820,5120,5121,5122,5124],{},"Asynchronous serial port read\u002Fwrite requires ",[28,5123,1830],{}," driver.",[1820,5126,5127,5129],{},[28,5128,1824],{}," is suitable for reading text protocols that end with a newline.",[1820,5131,5132,5133,5136],{},"Binary protocol is more suitable for ",[28,5134,5135],{},"async_read_some()"," with its own frame parser.",[1820,5138,5139],{},"Asynchronous writes must be mindful of the buffer lifecycle.",[1820,5141,5142],{},"In engineering, it is recommended to encapsulate serial port read\u002Fwrite into a class and manage sending data with a queue.",[5144,5145,5146],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":26,"searchDepth":219,"depth":219,"links":5148},[5149,5153,5162,5171,5180,5189,5198],{"id":43,"depth":219,"text":44,"children":5150},[5151,5152],{"id":55,"depth":227,"text":56},{"id":107,"depth":227,"text":108},{"id":171,"depth":219,"text":5154,"children":5155},"Example 1: Synchronously open the serial port and send a line in ordinary main()",[5156,5157,5158,5159,5160,5161],{"id":178,"depth":227,"text":179},{"id":199,"depth":227,"text":200},{"id":953,"depth":227,"text":954},{"id":1035,"depth":227,"text":1036},{"id":1059,"depth":227,"text":1060},{"id":1070,"depth":227,"text":1071},{"id":1142,"depth":219,"text":5163,"children":5164},"Example 2: Synchronously read a line of serial data in a normal main()",[5165,5166,5167,5168,5169,5170],{"id":1148,"depth":227,"text":179},{"id":1156,"depth":227,"text":200},{"id":1647,"depth":227,"text":954},{"id":1726,"depth":227,"text":1036},{"id":1767,"depth":227,"text":1060},{"id":1779,"depth":227,"text":1071},{"id":1806,"depth":219,"text":5172,"children":5173},"Example 3: Asynchronously reading a line of serial data in a regular main()",[5174,5175,5176,5177,5178,5179],{"id":1812,"depth":227,"text":179},{"id":1845,"depth":227,"text":200},{"id":2523,"depth":227,"text":954},{"id":2599,"depth":227,"text":1036},{"id":2632,"depth":227,"text":1060},{"id":2660,"depth":227,"text":2661},{"id":2754,"depth":219,"text":2755,"children":5181},[5182,5183,5184,5185,5186,5187,5188],{"id":2758,"depth":227,"text":179},{"id":2767,"depth":227,"text":200},{"id":3715,"depth":227,"text":954},{"id":3813,"depth":227,"text":1036},{"id":3841,"depth":227,"text":1060},{"id":3872,"depth":227,"text":3873},{"id":3910,"depth":227,"text":3911},{"id":3988,"depth":219,"text":3989,"children":5190},[5191,5192,5193,5194,5195,5196],{"id":3992,"depth":227,"text":179},{"id":4017,"depth":227,"text":200},{"id":4917,"depth":227,"text":954},{"id":4987,"depth":227,"text":1036},{"id":5006,"depth":227,"text":1060},{"id":5043,"depth":227,"text":5197},"async_write() Description",{"id":5112,"depth":219,"text":5113},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin","2100-0100-0300","2023-10-05","wiki\u002F2023-10-05-cplusplus-jiao-xue","en-us:2023-10-05-cplusplus-jiao-xue","\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue","Cplusplus教学","md","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0300-串口通信",false,null,"en-US","en-us",{},{"title":5,"description":26},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0300-串口通信","VnhwnBacpwylPAN_wLtKnb7zgIeCAPNAICLWkSrtZGg",[5218,5224,5229,5234,5239,5244,5249,5254,5259,5264,5269,5274,5279,5284,5289,5294,5299,5304,5309,5314,5319,5324,5329,5334,5339,5344,5349,5354,5359,5364,5369,5374,5379,5384,5389,5394,5399,5404,5409,5414,5419,5424,5429,5434,5439,5444,5449,5454,5459,5464,5468,5473,5478,5483,5488,5493,5498,5503,5508,5513,5518,5523,5528,5533,5538,5543,5544,5549,5554,5559,5564,5569,5574,5579,5584,5589,5594,5599,5604,5609,5614,5619],{"path":5219,"stem":5220,"title":5221,"date":5201,"chapterOrder":5222,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0100-c-kai-fa-huan-jing-da-jian-yu-ce-shi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0100-C++开发环境搭建与测试","C++ Development Environment Setup and Testing","0100",0,{"path":5225,"stem":5226,"title":5227,"date":5201,"chapterOrder":5228,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0200-c-ji-chu-chu-shi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0200-C++基础初识","C++ Basics","0200",{"path":5230,"stem":5231,"title":5232,"date":5201,"chapterOrder":5233,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0300-shu-ju-lei-xing-yu-shu-ju-cun-fang","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0300-数据类型与数据存放","Data Types and Data Storage","0300",{"path":5235,"stem":5236,"title":5237,"date":5201,"chapterOrder":5238,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0400-shu-ru-shu-chu","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0400-输入输出","Input and Output","0400",{"path":5240,"stem":5241,"title":5242,"date":5201,"chapterOrder":5243,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0500-yun-suan-fu","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0500-运算符","operator","0500",{"path":5245,"stem":5246,"title":5247,"date":5201,"chapterOrder":5248,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0600-cheng-xu-liu-cheng-jie-gou","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0600-程序流程结构","program flow structure","0600",{"path":5250,"stem":5251,"title":5252,"date":5201,"chapterOrder":5253,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0700-shu-zu","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0700-数组","array","0700",{"path":5255,"stem":5256,"title":5257,"date":5201,"chapterOrder":5258,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0800-han-shu-yu-tou-wen-jian","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0800-函数与头文件","Functions and Header Files","0800",{"path":5260,"stem":5261,"title":5262,"date":5201,"chapterOrder":5263,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0900-zhi-zhen","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0900-指针","pointer","0900",{"path":5265,"stem":5266,"title":5267,"date":5201,"chapterOrder":5268,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1000-jie-gou-ti-yu-gong-yong-ti","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1000-结构体与共用体","Structures and Unions","1000",{"path":5270,"stem":5271,"title":5272,"date":5201,"chapterOrder":5273,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1100-nei-cun-fen-qu-yu-sheng-ming-zhou-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1100-内存分区与生命周期","Memory Partitioning and Lifecycle","1100",{"path":5275,"stem":5276,"title":5277,"date":5201,"chapterOrder":5278,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1200-yin-yong","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1200-引用","reference","1200",{"path":5280,"stem":5281,"title":5282,"date":5201,"chapterOrder":5283,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1300-han-shu-ti-gao-yu-ming-ming-kong-jian","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1300-函数提高与命名空间","Advanced Functions and Namespaces","1300",{"path":5285,"stem":5286,"title":5287,"date":5201,"chapterOrder":5288,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0100-feng-zhuang","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-0100-封装","encapsulation","1400-0100",{"path":5290,"stem":5291,"title":5292,"date":5201,"chapterOrder":5293,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0200-dui-xiang-chu-shi-hua-he-qing-li","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-0200-对象初始化和清理","Object initialization and cleanup","1400-0200",{"path":5295,"stem":5296,"title":5297,"date":5201,"chapterOrder":5298,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0300-dui-xiang-mo-xing-yu-this-zhi-zhen","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-0300-对象模型与this指针","Object Model and the `this` Pointer","1400-0300",{"path":5300,"stem":5301,"title":5302,"date":5201,"chapterOrder":5303,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0400-you-yuan-yu-yun-suan-fu-zhong-zai","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-0400-友元与运算符重载","Friends and operator overloading","1400-0400",{"path":5305,"stem":5306,"title":5307,"date":5201,"chapterOrder":5308,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0500-ji-cheng","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-0500-继承","inheritance","1400-0500",{"path":5310,"stem":5311,"title":5312,"date":5201,"chapterOrder":5313,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0600-duo-tai","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-0600-多态","polymorphism","1400-0600",{"path":5315,"stem":5316,"title":5317,"date":5201,"chapterOrder":5318,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-lei-he-dui-xiang","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-类和对象","Classes and Objects","1400",{"path":5320,"stem":5321,"title":5322,"date":5201,"chapterOrder":5323,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1500-wen-jian-cao-zuo","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1500-文件操作","File operations","1500",{"path":5325,"stem":5326,"title":5327,"date":5201,"chapterOrder":5328,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1600-yi-chang-chu-li-yu-cuo-wu-ma","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1600-异常处理与错误码","异常处理","1600",{"path":5330,"stem":5331,"title":5332,"date":5201,"chapterOrder":5333,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1700-mu-ban","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1700-模板","template","1700",{"path":5335,"stem":5336,"title":5337,"date":5201,"chapterOrder":5338,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0100-stl-chu-shi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0100-STL初识","Introduction to STL","1800-0100",{"path":5340,"stem":5341,"title":5342,"date":5201,"chapterOrder":5343,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0200-std-array","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0200-std-array","std::array","1800-0200",{"path":5345,"stem":5346,"title":5347,"date":5201,"chapterOrder":5348,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0300-string-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0300-string容器","string container","1800-0300",{"path":5350,"stem":5351,"title":5352,"date":5201,"chapterOrder":5353,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0400-vector-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0400-vector容器","vector 容器","1800-0400",{"path":5355,"stem":5356,"title":5357,"date":5201,"chapterOrder":5358,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0500-deque-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0500-deque容器","deque 容器","1800-0500",{"path":5360,"stem":5361,"title":5362,"date":5201,"chapterOrder":5363,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0600-stack-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0600-stack容器","stack 容器","1800-0600",{"path":5365,"stem":5366,"title":5367,"date":5201,"chapterOrder":5368,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0700-queue-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0700-queue容器","queue container","1800-0700",{"path":5370,"stem":5371,"title":5372,"date":5201,"chapterOrder":5373,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0800-list-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0800-list容器","list 容器","1800-0800",{"path":5375,"stem":5376,"title":5377,"date":5201,"chapterOrder":5378,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0900-set-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0900-set容器","set \u002F multiset 容器","1800-0900",{"path":5380,"stem":5381,"title":5382,"date":5201,"chapterOrder":5383,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-1000-map-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-1000-map容器","map \u002F multimap 容器","1800-1000",{"path":5385,"stem":5386,"title":5387,"date":5201,"chapterOrder":5388,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-1100-han-shu-dui-xiang-yu-wei-ci","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-1100-函数对象与谓词","Function objects and predicates","1800-1100",{"path":5390,"stem":5391,"title":5392,"date":5201,"chapterOrder":5393,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-1200-chang-yong-suan-fa","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-1200-常用算法","Common algorithms","1800-1200",{"path":5395,"stem":5396,"title":5397,"date":5201,"chapterOrder":5398,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-stl-ti-gao-bian-cheng","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-STL提高编程","Level up your programming with STL.","1800",{"path":5400,"stem":5401,"title":5402,"date":5201,"chapterOrder":5403,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1900-c-lei-xing-zhuan-huan","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1900-C++类型转换","C++ Type Casting","1900",{"path":5405,"stem":5406,"title":5407,"date":5201,"chapterOrder":5408,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0100-auto","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0100-auto","auto","2000-0100",{"path":5410,"stem":5411,"title":5412,"date":5201,"chapterOrder":5413,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0200-nullptr","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0200-nullptr","nullptr","2000-0200",{"path":5415,"stem":5416,"title":5417,"date":5201,"chapterOrder":5418,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0300-using","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0300-using","using","2000-0300",{"path":5420,"stem":5421,"title":5422,"date":5201,"chapterOrder":5423,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0400-enum-class","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0400-enum-class","enum class","2000-0400",{"path":5425,"stem":5426,"title":5427,"date":5201,"chapterOrder":5428,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0500-fan-wei-for-xun-huan","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0500-范围for循环","range-based for loop","2000-0500",{"path":5430,"stem":5431,"title":5432,"date":5201,"chapterOrder":5433,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0600-jie-gou-hua-bang-ding","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0600-结构化绑定","structured binding","2000-0600",{"path":5435,"stem":5436,"title":5437,"date":5201,"chapterOrder":5438,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0700-constexpr","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0700-constexpr","constexpr","2000-0700",{"path":5440,"stem":5441,"title":5442,"date":5201,"chapterOrder":5443,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0800-raii","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0800-RAII","RAII","2000-0800",{"path":5445,"stem":5446,"title":5447,"date":5201,"chapterOrder":5448,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0900-zhi-neng-zhi-zhen","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0900-智能指针","Smart pointer","2000-0900",{"path":5450,"stem":5451,"title":5452,"date":5201,"chapterOrder":5453,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1000-you-zhi-yin-yong-he-yi-dong-yu-yi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1000-右值引用和移动语义","Rvalue references and move semantics","2000-1000",{"path":5455,"stem":5456,"title":5457,"date":5201,"chapterOrder":5458,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1100-lambda-biao-da-shi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1100-Lambda表达式","Lambda expression","2000-1100",{"path":5460,"stem":5461,"title":5462,"date":5201,"chapterOrder":5463,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1200-std-function","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1200-std-function","std::function","2000-1200",{"path":5465,"stem":5466,"title":35,"date":5201,"chapterOrder":5467,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1300-std-bind","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1300-std-bind","2000-1300",{"path":5469,"stem":5470,"title":5471,"date":5201,"chapterOrder":5472,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1400-std-optional","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1400-std-optional","std::optional","2000-1400",{"path":5474,"stem":5475,"title":5476,"date":5201,"chapterOrder":5477,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1500-std-variant","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1500-std-variant","std::variant","2000-1500",{"path":5479,"stem":5480,"title":5481,"date":5201,"chapterOrder":5482,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1600-std-span","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1600-std-span","std::span","2000-1600",{"path":5484,"stem":5485,"title":5486,"date":5201,"chapterOrder":5487,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1700-std-format-print","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1700-std-format-print","std::format \u002F std::print","2000-1700",{"path":5489,"stem":5490,"title":5491,"date":5201,"chapterOrder":5492,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1800-std-chrono","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1800-std-chrono","std::chrono","2000-1800",{"path":5494,"stem":5495,"title":5496,"date":5201,"chapterOrder":5497,"chapterDepth":219,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0100-std-thread","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0100-std-thread","std::thread and join","2000-1900-0100",{"path":5499,"stem":5500,"title":5501,"date":5201,"chapterOrder":5502,"chapterDepth":219,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0200-mutex-lock-guard","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0200-mutex-lock-guard","mutex 与 lock_guard","2000-1900-0200",{"path":5504,"stem":5505,"title":5506,"date":5201,"chapterOrder":5507,"chapterDepth":219,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0300-std-atomic","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0300-std-atomic","std::atomic","2000-1900-0300",{"path":5509,"stem":5510,"title":5511,"date":5201,"chapterOrder":5512,"chapterDepth":219,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0400-condition-variable","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0400-condition-variable","condition_variable","2000-1900-0400",{"path":5514,"stem":5515,"title":5516,"date":5201,"chapterOrder":5517,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-bing-fa-bian-cheng","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-并发编程","Concurrent programming","2000-1900",{"path":5519,"stem":5520,"title":5521,"date":5201,"chapterOrder":5522,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-2000-std-filesystem","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-2000-std-filesystem","std::filesystem","2000-2000",{"path":5524,"stem":5525,"title":5526,"date":5201,"chapterOrder":5527,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-2100-modules-jian-jie","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-2100-modules简介","Modules Introduction","2000-2100",{"path":5529,"stem":5530,"title":5531,"date":5201,"chapterOrder":5532,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-xian-dai-c","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-现代C++","Modern C++","2000",{"path":5534,"stem":5535,"title":5536,"date":5201,"chapterOrder":5537,"chapterDepth":219,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0100-ding-shi-qi-yu-yi-bu-io","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0100-定时器与异步IO","Timers and Asynchronous I\u002FO","2100-0100-0100",{"path":5539,"stem":5540,"title":5541,"date":5201,"chapterOrder":5542,"chapterDepth":219,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0200-boost-asio-ji-chu","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0200-Boost.Asio基础","Boost.Asio Basics","2100-0100-0200",{"path":5199,"stem":5215,"title":5,"date":5201,"chapterOrder":5200,"chapterDepth":219,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},{"path":5545,"stem":5546,"title":5547,"date":5201,"chapterOrder":5548,"chapterDepth":219,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0400-tcp-tong-xin","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0400-TCP通信","TCP communication","2100-0100-0400",{"path":5550,"stem":5551,"title":5552,"date":5201,"chapterOrder":5553,"chapterDepth":219,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0500-udp-tong-xin","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0500-UDP通信","UDP communication","2100-0100-0500",{"path":5555,"stem":5556,"title":5557,"date":5201,"chapterOrder":5558,"chapterDepth":219,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0600-ji-qi-ren-gong-cheng-xie-fa-yu-ros2-ji-cheng","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0600-机器人工程写法与ROS2集成","Robot Engineering Approach and ROS2 Integration","2100-0100-0600",{"path":5560,"stem":5561,"title":5562,"date":5201,"chapterOrder":5563,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-boost-asio-yi-bu-io-ku","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-Boost.Asio异步IO库","Boost.Asio asynchronous IO library","2100-0100",{"path":5565,"stem":5566,"title":5567,"date":5201,"chapterOrder":5568,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0200-eigen-xian-xing-dai-shu-ku","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0200-Eigen线性代数库","Eigen linear algebra library","2100-0200",{"path":5570,"stem":5571,"title":5572,"date":5201,"chapterOrder":5573,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0300-opencv-ji-suan-ji-shi-jue-ku","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0300-OpenCV计算机视觉库","OpenCV Computer Vision Library","2100-0300",{"path":5575,"stem":5576,"title":5577,"date":5201,"chapterOrder":5578,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0400-pcl-dian-yun-ku","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0400-PCL点云库","PCL Point Cloud Library","2100-0400",{"path":5580,"stem":5581,"title":5582,"date":5201,"chapterOrder":5583,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0500-sophus-li-qun-li-dai-shu-ku","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0500-Sophus李群李代数库","Sophus Lie group and Lie algebra library","2100-0500",{"path":5585,"stem":5586,"title":5587,"date":5201,"chapterOrder":5588,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-chang-yong-ku","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-常用库","Learning Common Libraries","2100",{"path":5590,"stem":5591,"title":5592,"date":5201,"chapterOrder":5593,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0100-cmakepresets-yu-gou-jian-an-zhuang","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2200-0100-CMakePresets与构建安装","CMakePresets and Build Installation","2200-0100",{"path":5595,"stem":5596,"title":5597,"date":5201,"chapterOrder":5598,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0200-ding-ceng-cmake-yu-gong-gong-bian-yi-xuan-xiang","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2200-0200-顶层CMake与公共编译选项","Top-level CMake and Public Compilation Options","2200-0200",{"path":5600,"stem":5601,"title":5602,"date":5201,"chapterOrder":5603,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0300-src-yu-lib-mo-kuai-cmake-xiang-jie","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2200-0300-src与lib模块CMake详解","Detailed CMake Explanation for src and lib Modules","2200-0300",{"path":5605,"stem":5606,"title":5607,"date":5201,"chapterOrder":5608,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0400-di-san-fang-ku-yi-lai-xie-fa","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2200-0400-第三方库依赖写法","How to write third-party library dependencies","2200-0400",{"path":5610,"stem":5611,"title":5612,"date":5201,"chapterOrder":5613,"chapterDepth":71,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0500-mu-ban-kuo-zhan-yu-chang-jian-wen-ti","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2200-0500-模板扩展与常见问题","Template Extensions and FAQ","2200-0500",{"path":5615,"stem":5616,"title":5617,"date":5201,"chapterOrder":5618,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":5208},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-cmake-gong-cheng-mu-ban","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2200-CMake工程模板","CMake Project Template","2200",{"path":5204,"stem":5620,"title":5621,"date":5201,"chapterOrder":5209,"chapterDepth":5223,"docKey":5203,"docRoot":5204,"docTitle":5205,"isWikiDoc":246,"isWikiIndex":246},"_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002Findex","C\u002FC++ tutorial",{"variants":5623},[5624,5625,5628,5631,5634],{"path":5199,"localeSlug":5211,"i18nKey":5207},{"path":5626,"localeSlug":5627,"i18nKey":5207},"\u002Fzh-hant\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin","zh-hant",{"path":5629,"localeSlug":5630,"i18nKey":5207},"\u002Fzh-hk\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin","zh-hk",{"path":5632,"localeSlug":5633,"i18nKey":5207},"\u002Fzh-tw\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin","zh-tw",{"path":5635,"localeSlug":5636,"i18nKey":5207},"\u002Fzh-cn\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin","zh-cn",[5199,5214,5626,5214,5629,5214,5632,5214,5635,5214],1784646870745]