-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
494 lines (237 loc) · 142 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Docker入门</title>
<link href="89826705/"/>
<url>89826705/</url>
<content type="html"><![CDATA[<h3 id="tldr"><a href="#tldr" class="headerlink" title="tldr;"></a>tldr;</h3><ul><li><code>docker images</code> 查看当前本地所有的镜像</li><li><code>docker ps</code> 当前所有创建的容器状态</li><li><code>docker pull image_name</code> 从官方仓库拉取镜像</li><li><code>docker exec -it --name [container_id | container_name] bash</code> 交互式连接一个正在运行的容器</li><li><code>docker rm container_id</code> 删除一个容器</li><li><code>docker [start|stop|restart] container_id</code> 启动、停止、重启一个容器</li></ul><a id="more"></a><h2 id="创建容器"><a href="#创建容器" class="headerlink" title="创建容器"></a>创建容器</h2><p><code>docker run [OPTIONS] IMAGE [COMMAND] [ARG...]</code></p><ul><li><p>docker run -it image_id –name define_name bash</p><p>run之后 容器就已经启动了</p></li><li><p>docker 挂载宿主机目录</p><p><code>docker run -it -v [宿主机目录]:[容器目录] --name [容器名] [完整镜像名 或者 镜像id] bash</code></p></li></ul><h2 id="启动与登陆"><a href="#启动与登陆" class="headerlink" title="启动与登陆"></a>启动与登陆</h2><ul><li><p>docker start CONTAINER_ID</p><p>启动一个容器</p></li><li><p>docker exec -it name|container_id bash</p><p>交互式连接容器</p></li></ul><h2 id="创建镜像"><a href="#创建镜像" class="headerlink" title="创建镜像"></a>创建镜像</h2><p>容器创建有两种方式</p><ul><li>登陆容器,配置之后commit</li><li>通过dockerfile 创建 </li></ul><blockquote><p>官方推荐使用dockerfile的方式</p></blockquote><h3 id="通过Dockerfile创建docker"><a href="#通过Dockerfile创建docker" class="headerlink" title="通过Dockerfile创建docker"></a>通过Dockerfile创建docker</h3><ol><li>写Dockerfile</li><li><code>docker build -t image_name:v1 .</code><ul><li>RUN 会执行命令</li><li>COPY会拷贝当前目录中的文件到docker中</li></ul></li><li>docker run</li></ol><p>未完,后续有时间更新…</p><hr><p>参考连接:</p>]]></content>
<categories>
<category> tool </category>
</categories>
<tags>
<tag> tool </tag>
</tags>
</entry>
<entry>
<title>Vim开发环境</title>
<link href="977574a9/"/>
<url>977574a9/</url>
<content type="html"><![CDATA[<h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><p> 个人搭建的vim C++开发环境, 使用coc.nvim框架 + ccls 提供补全服务。实现基本的语意补全、跳转,查找引用等功能。原则是尽量不修改vim原生按键功能。</p><p> 仓库地址:<a href="https://github.com/skywb/vim-config" target="_blank" rel="noopener">https://github.com/skywb/vim-config</a></p><p> 简介于教程后续有时间更新….</p><a id="more"></a><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><h3 id="依赖"><a href="#依赖" class="headerlink" title="依赖"></a>依赖</h3><ul><li>需要提前安装ccls或其它ls</li><li>nodejs > 10</li><li>python3</li></ul><h3 id="安装-1"><a href="#安装-1" class="headerlink" title="安装"></a>安装</h3><p> 直接将<a href="https://github.com/skywb/vim-config" target="_blank" rel="noopener">github仓库</a>克隆到本地, 并更新submodule,覆盖~/.vim 文件夹。 <code>请自行备份原来的文件夹</code></p><p> 创建一个软连接<code>.vimrc</code>指向.vim/vimrc</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">cd ~</span><br><span class="line">mv -r .vim .vim.back</span><br><span class="line">mv .vimrc .vimrc.back</span><br><span class="line">git clone --depth 1 https://github.com/skywb/vim-config.git ./.vim</span><br><span class="line">ln -s .vim/vimrc ./.vimrc</span><br><span class="line">cd .vim/</span><br><span class="line">git submodule init</span><br><span class="line">git submodule update</span><br></pre></td></tr></table></figure><p> 第一次启动是默认会安装几个插件</p><h2 id="基本使用"><a href="#基本使用" class="headerlink" title="基本使用"></a>基本使用</h2><h3 id="项目配置"><a href="#项目配置" class="headerlink" title="项目配置"></a>项目配置</h3><h4 id="ccls"><a href="#ccls" class="headerlink" title="ccls"></a>ccls</h4><ul><li><p>根目录</p><p>ccls 会向上查找根目录,标志文件为 <code>[".ccls", "compile_commands.json", ".git/"]</code> </p></li></ul><blockquote><p> 可以通过 :CocConfig 命令打开配置文件,自行设置 rootParrerns 参数</p></blockquote><ul><li><p>补全设置</p><p>ccls依赖compile_commands.json检索对应关键字</p><p>cmake 可以在构建是指定宏<code>-DCMAKE_EXPORT_COMPILE_COMMANDS=YES</code> 生成</p><p>若只使用make的老项目,可以通过bear工具生成<code>bear make -j$(nproc)</code></p><p><a href="https://github.com/MaskRay/ccls/wiki/Project-Setup" target="_blank" rel="noopener">ccls官方说明</a></p></li></ul><h3 id="基本功能"><a href="#基本功能" class="headerlink" title="基本功能"></a>基本功能</h3><h4 id="补全"><a href="#补全" class="headerlink" title="补全"></a>补全</h4><p> 默认开启语意补全,输入前两个字母或者<code>.</code> <code>-></code> 等触发。</p><p> 触发补全列表时, 可通过方向键、<code><C-n></code> 下一个,<code><C-p</code>上一个等选择候选</p><blockquote><p>按键说明约定:</p><p> 与vim官方文档表示相同。</p><p> <C-> 表示 ctrl + 某按键, 例如 <C-n> 表示 ctrl + n</C-n></C-></p><p> <leader> 键可以自行设置,默认是 \</leader></p><p> <CR> 表示回车</CR></p></blockquote><h3 id="跳转"><a href="#跳转" class="headerlink" title="跳转"></a>跳转</h3><ul><li>gd 跳转到定义 (一般都是跳转到实现)</li><li>gc 跳转到声明</li><li>gi 跳转到实现 (不怎么用,gd更顺手)</li><li>gf 跳转到文件</li><li>gr 跳转到引用</li></ul><h4 id="查找文件"><a href="#查找文件" class="headerlink" title="查找文件"></a>查找文件</h4><ul><li><p>默认配置了leaderF, 并设置快捷键<code><leader>ff</code></p></li><li><p>Coc配置安装了 coc-lists, 包含files功能,可以搜索文件, 可以通过 <code>:CocList fiels</code> 或 <code><C-l></code> 换起 coclist选择files唤起</p><p> 但是files不支持仅匹配文件名,当路径很长时,体验不太好,我更喜欢leaderF</p></li></ul><h4 id="snippet"><a href="#snippet" class="headerlink" title="snippet"></a>snippet</h4><p> 通过代码块快速生成代码模板</p><p> 默认加载 <code>https://github.com/skywb/snippets</code> 的仓库, 目前只有c++ 代码模板,可以加载其它仓库 例如: <code>https://github.com/honza/vim-snippets</code> 、<code>https://github.com/SirVer/ultisnips</code></p><ul><li><p>触发</p><p>当输入snippet 的key是,默认触发补全列表,选中后 <code><C-y></code> 展开</p><p><img src="https://raw.githubusercontent.com/skywb/PictureBed-PicGo/master/other/snippet.gif" alt="snippet.gif"></p></li><li><p>如需要更多snippet文件,可直接添加到<code>.vim/snippet</code> 下即可</p></li></ul><h4 id="CocList-功能补充"><a href="#CocList-功能补充" class="headerlink" title="CocList 功能补充"></a>CocList 功能补充</h4><ul><li>files 查找文件</li><li>outline 当前文件下所有方法、类、变量等</li><li>commands 所有支持的命令,可以自定义添加。详情请阅读coc.nvim 文档</li><li>其他</li></ul><h2 id="Command"><a href="#Command" class="headerlink" title="Command"></a>Command</h2><h2 id="快捷键补充"><a href="#快捷键补充" class="headerlink" title="快捷键补充"></a>快捷键补充</h2><ul><li><p>拓展a和i的能力</p><ul><li>if 整个方法内部</li><li>af 整个方法</li><li>ic class内部</li><li>ac 整个class</li></ul></li><li><p><code>gp</code> 选中刚刚粘贴的内容</p><blockquote><p>技巧:</p><p> 当存他处赋值了代码,粘贴后 gp= 可快速格式化</p></blockquote></li></ul><hr><p>参考连接:</p><p><a href="https://github.com/MaskRay/ccls/wiki/Project-Setup" target="_blank" rel="noopener">https://github.com/MaskRay/ccls/wiki/Project-Setup</a></p>]]></content>
<categories>
<category> vim </category>
</categories>
<tags>
<tag> tool </tag>
<tag> vim </tag>
</tags>
</entry>
<entry>
<title>vim C++开发环境搭建</title>
<link href="ecad5b71/"/>
<url>ecad5b71/</url>
<content type="html"><![CDATA[<h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><p>基于vim8.2、coc.nvim + ccls 搭建C++开发环境。尽量不修改vim原生按键。提供语意补全和语意跳转查找引用等基本功能。</p><a id="more"></a><h2 id="依赖环境"><a href="#依赖环境" class="headerlink" title="依赖环境"></a>依赖环境</h2><p><code>cmake, git, nodejs, python3, python3-dev</code></p><ul><li><p>安装依赖:</p><p>centos:</p><p><code>yum install -y cmake git nodejs python3 python3-devel</code></p><p>ubuntu:</p><p><code>apt install -y cmake git nodejs python3 python3-dev</code></p></li><li><p>卸载系统绑定vim</p><blockquote><p>若vim 为 8.2及以上版本可以不卸载,并跳过源码安装vim</p></blockquote><p>centos:</p><p><code>yum remove vim</code></p></li><li><p>安装vim8.2</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">git clone --depth 1 -b v8.2.1052 https://github.com/vim/vim.git</span><br><span class="line"><span class="meta">#</span><span class="bash"> 到vim目录下</span></span><br><span class="line">cd vim</span><br><span class="line">./configure --with-features=huge \</span><br><span class="line"> --enable-multibyte \</span><br><span class="line"> --enable-python3interp \</span><br><span class="line"> --with-python3-config-dir=/usr/lib64/python3.6/config-3.6m-x86_64-linux-gnu \</span><br><span class="line"> --prefix=/usr/local/vim8</span><br><span class="line"></span><br><span class="line">make -j8</span><br><span class="line">make install</span><br></pre></td></tr></table></figure></li></ul><h2 id="编译安装-LLVM-Clang"><a href="#编译安装-LLVM-Clang" class="headerlink" title="编译安装 LLVM+Clang"></a>编译安装 LLVM+Clang</h2><blockquote><p>若llvm和clang版本足够新,并且安装了clang-tools-extra 可以直接使用,无需源码安装</p><p>若系统为Ubuntu等常见系统,可以直接使用官网上与构建版本的二进制包 <a href="https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz" target="_blank" rel="noopener">Pre-Built Binaries https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz</a></p><p>ubuntu版本的可能适配多种系统,若不愿意源码构建,可尝试一下</p></blockquote><p>需要下载四个源码,并放到同一个目录下面,安装编译即可,编译完成默认会放到系统目录中 (不同系统路径可能有所差异) </p><blockquote><p>如需修改安装路径请自行修改安装脚本,若不懂请不要随意修改,避免发生错误不知如何操作</p><p>安装其他版本,替换源码的版本号即可,若不懂请不要随意修改,避免发生错误不知如何操作</p></blockquote><ul><li>安装脚本:</li></ul><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">mkdir llvm_src</span><br><span class="line">cd llvm_src</span><br><span class="line">wget https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/llvm-11.0.0.src.tar.xz</span><br><span class="line">tar xf llvm-11.0.0.src.tar.xz</span><br><span class="line">mv llvm-11.0.0.src llvm</span><br><span class="line">wget https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/clang-11.0.0.src.tar.xz</span><br><span class="line">tar xf clang-11.0.0.src.tar.xz</span><br><span class="line">mv clang-11.0.0.src clang</span><br><span class="line">wget https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/libcxx-11.0.0.src.tar.xz</span><br><span class="line">tar xf libcxx-11.0.0.src.tar.xz</span><br><span class="line">mv libcxx-11.0.0.src libcxx</span><br><span class="line">wget https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/libcxxabi-11.0.0.src.tar.xz</span><br><span class="line">tar xf libcxxabi-11.0.0.src.tar.xz</span><br><span class="line">mv libcxxabi-11.0.0.src.tar.xz libcxxabi</span><br><span class="line">wget https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/clang-tools-extra-11.0.0.src.tar.xz</span><br><span class="line">tar xf clang-tools-extra-11.0.0.src.tar.xz</span><br><span class="line">mv clang-tools-extra-11.0.0.src.tar.xz clang-tools-extra</span><br><span class="line"><span class="meta">#</span><span class="bash"> build</span></span><br><span class="line">mkdir Release</span><br><span class="line">cd Release</span><br><span class="line">cmake ../llvm -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi;clang-tools-extra;"</span><br><span class="line">make -j8</span><br><span class="line">make install</span><br><span class="line"><span class="meta">#</span><span class="bash"> delete tmp and src files</span></span><br><span class="line">cd ..</span><br><span class="line">rm -rf llvm_src</span><br></pre></td></tr></table></figure><blockquote><p>此脚本为纯手打,未执行过,如有错误请及时反馈</p></blockquote><h2 id="下载vim配置"><a href="#下载vim配置" class="headerlink" title="下载vim配置"></a>下载vim配置</h2><p> 使用的是skywb的配置,如果有其他的配置请自行下载或使用</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">cd ~</span><br><span class="line">mv .vim .vim.back # 如不需要备份请直接删除</span><br><span class="line">mkdir .vim</span><br><span class="line">git clone --depth 1 https://github.com/skywb/vim-config.git ./.vim</span><br><span class="line">mv .vimrc .vimrc.back # 如不需要备份请直接删除</span><br><span class="line">ln -s .vim/vimrc ./.vimrc</span><br><span class="line">cd .vim/</span><br><span class="line">git submodule init</span><br><span class="line">git submodule update</span><br><span class="line">vim -c ":PlugInstall" -c "q"</span><br></pre></td></tr></table></figure><p>由于coc.nvim版本里存在部分问题,需要手动执行 :PlugInstall</p><hr><p>参考连接:</p>]]></content>
<tags>
<tag> tool </tag>
</tags>
</entry>
<entry>
<title>Conan使用入门</title>
<link href="1ebe501c/"/>
<url>1ebe501c/</url>
<content type="html"><![CDATA[<h2 id="tl-dr"><a href="#tl-dr" class="headerlink" title="tl;dr"></a>tl;dr</h2><p>Conan 是C++的一个包管理工具,使得C++安装第三方库变的很方便。 类似于vs的NuGet</p><p>Conan的基本命令:</p><ul><li><p>查找库: <code>conan search poco --remote=conan-center</code></p></li><li><p>安装库:<code>conan inspect poco/1.9.4</code></p></li><li><p>安装到项目:<code>conan install ..</code></p></li><li><p>conanfile.txt样例:</p> <figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[requires]</span><br><span class="line">poco/1.9.4</span><br><span class="line"></span><br><span class="line">[generators]</span><br><span class="line">cmake</span><br></pre></td></tr></table></figure></li><li><p>CMakeLists.txt 插入内容:</p> <figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">include</span>(<span class="variable">${CMAKE_BINARY_DIR}</span>/conanbuildinfo.cmake)</span><br><span class="line">conan_basic_setup()</span><br></pre></td></tr></table></figure></li></ul><a id="more"></a><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p>conan 依赖python,因此需要安装python, 最好是安装python3</p><p>然后使用命令安装即可</p><p><code>pip install conan</code></p><p>如果找不到pip命令, 一种原因是没有安装python,另一种是没将pip路径添加到path</p><p>自己还遇到了一种情况就是,在windows下,使用pip安装了之后,能找到这个程序,却找不多conan命令,就是找不到conan.exe可执行程序</p><p>这种情况一般是没将pip安装后的可执行程序的目录添加到path里, 用everything搜一下conan.exe在哪,把路径添加进去就好了。</p><h3 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h3><p> Conan 会在第一次启动时自动配置好默认的 Profile 和 Remote 设置。它的配置以及本地的二进制仓库均存储在用户目录下<code>~/.conan/</code>中(Windows上,是<code>%USERPROFILE%\.conan\</code>)。</p><p>其中用户配置文件为<code>conan.conf</code>,通常情况下无需修改,但当需要设置代理时,可以对其进行编辑。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[proxies]</span><br><span class="line">http = ####代理地址</span><br><span class="line">https = ####代理地址</span><br></pre></td></tr></table></figure><h2 id="包管理"><a href="#包管理" class="headerlink" title="包管理"></a>包管理</h2><p>官方文档中给出了一个项目demo, 顺便借助这个demo记录一下基本的使用。</p><h3 id="查找本地库"><a href="#查找本地库" class="headerlink" title="查找本地库"></a>查找本地库</h3><p><code>conan search</code> 可以查看本地已经缓存过的库有哪些</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Existing package recipes:</span><br><span class="line"></span><br><span class="line">boost/1.69.0</span><br><span class="line">bzip2/1.0.8</span><br><span class="line">openssl/1.0.2t</span><br><span class="line">poco/1.10.0</span><br><span class="line">zlib/1.2.11</span><br></pre></td></tr></table></figure><p>以上是执行后的结果,安装有五个库, <code>/</code> 后面表示版本号</p><h3 id="查找远程库"><a href="#查找远程库" class="headerlink" title="查找远程库"></a>查找远程库</h3><p>如果只是使用search则是在本地查找,如果版本可以接受可以直接用,避免总是从网上缓存过多的版本。</p><p><code>conan search poco --remote=conan-center</code> </p><p>通过 <code>--remote</code> 参数指定源, <code>conan-center</code>则是conan的官方库,里面有大部分库的封装。 如果使用个人的或其他的源,指定地址即可。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> conan search poco --remote=conan-center</span></span><br><span class="line">Existing package recipes:</span><br><span class="line"></span><br><span class="line">poco/1.8.1</span><br><span class="line">poco/1.9.3</span><br><span class="line">poco/1.9.4</span><br></pre></td></tr></table></figure><p>显示有多个版本,可以选择一个安装。</p><h3 id="安装远程的库"><a href="#安装远程的库" class="headerlink" title="安装远程的库"></a>安装远程的库</h3><p><code>conan inspect poco/1.9.4</code></p><p>通过此命令安装1.9.4版本的poco库, 等待执行结束即可。</p><p>这个时候如果再从本地查找就能找到这个库了。</p><h3 id="删除库"><a href="#删除库" class="headerlink" title="删除库"></a>删除库</h3><p><code>conan remove poco/1.9.4</code></p><p>会给予确认提示,确认后就可以删除了。</p><h2 id="项目编译"><a href="#项目编译" class="headerlink" title="项目编译"></a>项目编译</h2><h3 id="项目配置"><a href="#项目配置" class="headerlink" title="项目配置"></a>项目配置</h3><p>官方给出的demo代码</p><p>Demo.cpp</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"Poco/MD5Engine.h"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"Poco/DigestStream.h"</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span>** argv)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> Poco::MD5Engine md5;</span><br><span class="line"> <span class="function">Poco::DigestOutputStream <span class="title">ds</span><span class="params">(md5)</span></span>;</span><br><span class="line"> ds << <span class="string">"abcdefghijklmnopqrstuvwxyz"</span>;</span><br><span class="line"> ds.<span class="built_in">close</span>();</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << Poco::DigestEngine::digestToHex(md5.digest()) << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><blockquote><p>也可以从github上直接拉取</p><p><code>git clone https://github.com/conan-io/examples.git && cd examples/libraries/poco/md5</code></p></blockquote><p>然后我们需要在项目路径添加一个<code>conanfile.txt</code>文件, 文件内主要记录conan的配置,依赖的库,版本,以及生成工具等等。</p><p><strong>conanfile.txt</strong></p><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[requires]</span><br><span class="line">poco/1.9.4</span><br><span class="line"></span><br><span class="line">[generators]</span><br><span class="line">cmake</span><br></pre></td></tr></table></figure><p>构建工具使用cmake</p><h3 id="指定编译器版本信息"><a href="#指定编译器版本信息" class="headerlink" title="指定编译器版本信息"></a>指定编译器版本信息</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ conan profile update settings.compiler.libcxx=libstdc++11 default # Sets libcxx to C++11 ABI</span><br></pre></td></tr></table></figure><p>指定使用C++11编译</p><h3 id="安装库"><a href="#安装库" class="headerlink" title="安装库"></a>安装库</h3><p>例如我们需要构建到build目录</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> mkdir build && <span class="built_in">cd</span> build</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> conan install ..</span></span><br></pre></td></tr></table></figure><p>当我们使用 <code>install</code>之后,就会生成一个<code>conanbuildinfo.cmake</code>文件,文件里面主要是将库依赖,我们需要将这个文件写到我们项目的<code>CMakeLists.txt</code>里面</p><p><strong>CMakeLists.txt</strong></p><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">cmake_minimum_required</span>(VERSION <span class="number">2.8</span>.<span class="number">12</span>)</span><br><span class="line"><span class="keyword">project</span>(MD5Encrypter)</span><br><span class="line"></span><br><span class="line"><span class="keyword">add_definitions</span>(<span class="string">"-std=c++11"</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">include</span>(<span class="variable">${CMAKE_BINARY_DIR}</span>/conanbuildinfo.cmake)</span><br><span class="line">conan_basic_setup()</span><br><span class="line"></span><br><span class="line"><span class="keyword">add_executable</span>(Demo Demo.cpp)</span><br><span class="line"><span class="keyword">target_link_libraries</span>(Demo <span class="variable">${CONAN_LIBS}</span>)</span><br></pre></td></tr></table></figure><p>此时项目就配置好了。</p><h3 id="编译运行"><a href="#编译运行" class="headerlink" title="编译运行"></a>编译运行</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">(win)</span><br><span class="line"><span class="meta">$</span><span class="bash"> cmake .. -G <span class="string">"Visual Studio 16"</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> cmake --build . --config Release</span></span><br><span class="line"></span><br><span class="line">(linux, mac)</span><br><span class="line"><span class="meta">$</span><span class="bash"> cmake .. -G <span class="string">"Unix Makefiles"</span> -DCMAKE_BUILD_TYPE=Release</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> cmake --build .</span></span><br><span class="line">...</span><br><span class="line"><span class="meta">[100%</span><span class="bash">] Built target Demo</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> ./bin/Demo</span></span><br><span class="line">c3fcd3d76192e4007dfb496cca67e13b</span><br></pre></td></tr></table></figure><h3 id="关于头文件"><a href="#关于头文件" class="headerlink" title="关于头文件"></a>关于头文件</h3><p>如果使用了ide或者ls, 在项目中直接使用 “” 包含头文件即可。</p><h2 id="上传自己的包"><a href="#上传自己的包" class="headerlink" title="上传自己的包"></a>上传自己的包</h2><p>TODO: 目前还没用到,需要的时候再补充 需要的可以阅读下方参考连接里面的官方文档。</p><h2 id="搭建私有服务器"><a href="#搭建私有服务器" class="headerlink" title="搭建私有服务器"></a>搭建私有服务器</h2><p>TODO: 目前还没用到,需要的时候再补充</p><h2 id="参考连接:"><a href="#参考连接:" class="headerlink" title="参考连接:"></a>参考连接:</h2><ul><li><a href="https://docs.conan.io/en/latest/installation.html" target="_blank" rel="noopener">官方文档</a></li></ul>]]></content>
<categories>
<category> tool </category>
</categories>
<tags>
<tag> tool </tag>
<tag> conan </tag>
<tag> C++ </tag>
</tags>
</entry>
<entry>
<title>vscode+wsl编译调试C++工程</title>
<link href="95e6964/"/>
<url>95e6964/</url>
<content type="html"><![CDATA[<h2 id="tl-dr"><a href="#tl-dr" class="headerlink" title="tl;dr"></a>tl;dr</h2><p><a href="vscode:extension/ms-vscode-remote.remote-wsl">安装remote-WSL插件</a></p><p> <a href="vscode:extension/ms-vscode.cpptools">安装C++调试工具</a></p><p>在wsl中要安装gdb与对应的编译工具</p><p><code>code .</code> 可在vscode中打开当前文件夹,并远程连接。</p><p><img src="/95e6964/test2-1583203445737.gif" alt="效果"></p><a id="more"></a><hr><h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>虽然自己搭建的vim里面的调试也很好用了,在工具上依然不如可视化的调试环境好用,所以使用vscode自己折腾一下调试环境,平时自己写代码一般在wsl中,所以尝试用一下vscode的远程调试结合wsl。</p><p><a href="https://code.visualstudio.com/docs/cpp/config-wsl" target="_blank" rel="noopener">vscode给的文档相当清楚明白</a></p><p>说说主要的地方。</p><h3 id="安装WSl"><a href="#安装WSl" class="headerlink" title="安装WSl"></a>安装WSl</h3><p> 这里略过,参照其他的安装方法,网上很多。</p><h3 id="安装vsCode插件"><a href="#安装vsCode插件" class="headerlink" title="安装vsCode插件"></a>安装vsCode插件</h3><p>点击如图所示左边第五个图标,打开扩展市场,搜索里面的<a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl" target="_blank" rel="noopener">remote-WSl</a>插件, 也可以<a href="vscode:extension/ms-vscode-remote.remote-wsl">点此安装</a></p><p> <img src="/95e6964/image-20200303100745429.png" alt="image-20200303100745429"></p><h3 id="在wsl中打开vsCode"><a href="#在wsl中打开vsCode" class="headerlink" title="在wsl中打开vsCode"></a>在wsl中打开vsCode</h3><p> 在wsl中新建一个文件夹作为工程目录,例如我新建一个test文件加作为工程目录</p><p><img src="/95e6964/image-20200303101215609.png" alt="image-20200303101215609"></p><p>然后运行命令:<code>code .</code></p><p>首次运行的时候会出现安装提示,稍后会打开vscode, 发现vscode的底部状态栏有如下的状态。</p><p><img src="/95e6964/image-20200303101344778.png" alt="image-20200303101344778"></p><p>说明已经连接,并且此时vscode打开的目录就是你的工程目录。</p><p><img src="/95e6964/image-20200303101709216.png" alt="image-20200303101709216"></p><h3 id="编译配置文件"><a href="#编译配置文件" class="headerlink" title="编译配置文件"></a>编译配置文件</h3><p>此时如果需要编译,那么就需要添加编译配置,创建一个tasks.json 文件,设置编译相关的命令。也可以如下所示直接使用编译,vscode会提示创建tasks.json文件。</p><p><img src="/95e6964/image-20200303101755621.png" alt="image-20200303101755621"></p><p><img src="/95e6964/test.gif" alt="image-20200303102040565"></p><ul><li><p>生成的tasks.json为默认的内容,需要对其进行修改。</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">"tasks": [</span><br><span class="line"> {</span><br><span class="line"> "label": "build demo",</span><br><span class="line"> "type": "shell",</span><br><span class="line"> "command": "/usr/bin/g++",</span><br><span class="line"> "args": [</span><br><span class="line"> "-g",</span><br><span class="line"> "${file}",</span><br><span class="line"> "-o",</span><br><span class="line"> "${fileDirname}/${fileBasenameNoExtension}"</span><br><span class="line"> ],</span><br><span class="line"> "group": {</span><br><span class="line"> "kind": "build",</span><br><span class="line"> "isDefault": true</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> ]</span><br></pre></td></tr></table></figure><p> 以上配置需要在要编译的文件的页面进行编译,因为${file} 获取的是当前文件名,以上仅为例子,如果编译工程需要使用make或者cmake等工具跟上面使用方法一样,改变command和args即可。</p></li><li><p>再次重复上面,Terminal > Run Build Task 选择即可。</p></li></ul><h3 id="调试配置文件"><a href="#调试配置文件" class="headerlink" title="调试配置文件"></a>调试配置文件</h3><p>调试需要再安装一个拓展插件 <a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools" target="_blank" rel="noopener">C/C++</a>, <a href="vscode:extension/ms-vscode.cpptools">点击可安装</a></p><p><img src="/95e6964/image-20200303103515254.png" alt="image-20200303103515254"></p><ul><li>创建一个launch.json 文件,配置调试选项</li></ul><p><img src="/95e6964/test1-1583203167206.gif" alt></p><p>如图可以新建一个默认的编译并调试的launch.json文件,只需要对其简单修改即可</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">"configurations": [</span><br><span class="line"> {</span><br><span class="line"> "name": "g++ build and debug active file",</span><br><span class="line"> "type": "cppdbg",</span><br><span class="line"> "request": "launch",</span><br><span class="line"> "program": "${fileDirname}/${fileBasenameNoExtension}",</span><br><span class="line"> "args": [],</span><br><span class="line"> "stopAtEntry": false,</span><br><span class="line"> "cwd": "${workspaceFolder}",</span><br><span class="line"> "environment": [],</span><br><span class="line"> "externalConsole": false,</span><br><span class="line"> "MIMode": "gdb",</span><br><span class="line"> "setupCommands": [</span><br><span class="line"> {</span><br><span class="line"> "description": "Enable pretty-printing for gdb",</span><br><span class="line"> "text": "-enable-pretty-printing",</span><br><span class="line"> "ignoreFailures": true</span><br><span class="line"> }</span><br><span class="line"> ],</span><br><span class="line"> "preLaunchTask": "build demo", //编译的task的名称</span><br><span class="line"> "miDebuggerPath": "/usr/bin/gdb" //gdb的路径</span><br><span class="line"> }</span><br><span class="line"> ]</span><br></pre></td></tr></table></figure><p>这样就可以编译与调试了。</p><h4 id="编译与调试"><a href="#编译与调试" class="headerlink" title="编译与调试"></a>编译与调试</h4><p><img src="/95e6964/test2-1583203445737.gif" alt></p><h3 id="参考连接"><a href="#参考连接" class="headerlink" title="参考连接"></a>参考连接</h3><p><a href="https://code.visualstudio.com/docs/cpp/config-wsl" target="_blank" rel="noopener">https://code.visualstudio.com/docs/cpp/config-wsl</a></p>]]></content>
<categories>
<category> tool </category>
</categories>
<tags>
<tag> wsl </tag>
<tag> vscode </tag>
</tags>
</entry>
<entry>
<title>更新安装到WSL2</title>
<link href="de2aaebe/"/>
<url>de2aaebe/</url>
<content type="html"><![CDATA[<h2 id="tl-dr"><a href="#tl-dr" class="headerlink" title="tl;dr"></a>tl;dr</h2><p>必须是18917或更高版本:</p><p>powershell管理员运行:</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">dism.exe /online /<span class="built_in">enable-feature</span> /featurename:Microsoft<span class="literal">-Windows</span><span class="literal">-Subsystem</span><span class="literal">-Linux</span> /all /norestart</span><br><span class="line">dism.exe /online /<span class="built_in">enable-feature</span> /featurename:VirtualMachinePlatform /all /norestart</span><br></pre></td></tr></table></figure><p>检查当前使用的bash名</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wsl <span class="literal">-l</span></span><br></pre></td></tr></table></figure><p>设置版本:</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wsl -<span class="literal">-set</span><span class="literal">-version</span> <Distro> <span class="number">2</span></span><br><span class="line">wsl -<span class="literal">-set</span><span class="literal">-default</span><span class="literal">-version</span> <span class="number">2</span></span><br></pre></td></tr></table></figure><p>其中<Distro> 替换成对应的bash名字</p><a id="more"></a><h4 id="检查当前操作系统的版本"><a href="#检查当前操作系统的版本" class="headerlink" title="检查当前操作系统的版本"></a>检查当前操作系统的版本</h4><p>首先要保证当前的win10版本大于等于</p><ul><li><p>若要确保使用的是版本18917或更高版本,请加入<a href="https://insider.windows.com/en-us/" target="_blank" rel="noopener">Windows 预览体验计划</a>,并选择 “快速” 环或 “慢速” 环。</p><p> win+r 输入 winver 回车</p></li></ul><p><img src="/de2aaebe/image-20200229111630961.png" alt="image-20200229111630961"></p><p>显示当前的版本好小于18917, 因此需要更新到体验版本, 如果不小于则跳过本步骤。</p><h4 id="更新到体验版本"><a href="#更新到体验版本" class="headerlink" title="更新到体验版本"></a>更新到体验版本</h4><p><a href="ms-settings:windowsinsider">点击加入预览体验计划</a></p><p>然后按windows键,输入update回车, 打开更新系统的界面,然后下载安装即可,我这里已经下载安装了。</p><p><a href="ms-settings:windowsupdate">打开更新系统更新界面</a> 检查更新即可</p><p>更新完的版本:</p><p><img src="/de2aaebe/image-20200305094806220.png" alt="image-20200305094806220"></p><h4 id="更新到wsl2"><a href="#更新到wsl2" class="headerlink" title="更新到wsl2"></a>更新到wsl2</h4><p>powershell管理员运行:</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">dism.exe /online /<span class="built_in">enable-feature</span> /featurename:Microsoft<span class="literal">-Windows</span><span class="literal">-Subsystem</span><span class="literal">-Linux</span> /all /norestart</span><br><span class="line">dism.exe /online /<span class="built_in">enable-feature</span> /featurename:VirtualMachinePlatform /all /norestart</span><br></pre></td></tr></table></figure><p>检查当前使用的bash名</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wsl <span class="literal">-l</span></span><br></pre></td></tr></table></figure><p><img src="/de2aaebe/image-20200305094936007.png" alt="image-20200305094936007"></p><p>设置版本:</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wsl -<span class="literal">-set</span><span class="literal">-version</span> <Distro> <span class="number">2</span></span><br><span class="line">wsl -<span class="literal">-set</span><span class="literal">-default</span><span class="literal">-version</span> <span class="number">2</span></span><br></pre></td></tr></table></figure><p>其中<Distro> 替换成对应的bash名字 例如 Ubuntu-18.04</p><p>然后查看版本即可:</p><p><img src="/de2aaebe/image-20200305095020137.png" alt="image-20200305095020137"></p><p>参考连接:</p><p><a href="https://docs.microsoft.com/zh-cn/windows/wsl/wsl2-install" target="_blank" rel="noopener">https://docs.microsoft.com/zh-cn/windows/wsl/wsl2-install</a></p>]]></content>
<categories>
<category> tool </category>
</categories>
<tags>
<tag> tool </tag>
<tag> wsl </tag>
</tags>
</entry>
<entry>
<title>Pimpl 模式</title>
<link href="1fb7cb45/"/>
<url>1fb7cb45/</url>
<content type="html"><![CDATA[<p> Pimpl (pointer to implementation) 是一种将接口和具体的实现分开的一种方式,优化编译时间,保护封装实现的一种经验技巧。</p><h2 id="tl-dr"><a href="#tl-dr" class="headerlink" title="tl;dr"></a>tl;dr</h2><p> 就是说模块对外接口类里面不放实现,而是保存一个指针, 指向真正实现的类。然后在接口类里面同名方法通过指针调用真正实现方法。</p><a id="more"></a><p> </p><p> </p><h2 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h2><p> 通过指针的间接调用,实现消息的转发,使得行为与原来行为相同。</p><h2 id="Demo"><a href="#Demo" class="headerlink" title="Demo"></a>Demo</h2><h3 id="普通类的设计"><a href="#普通类的设计" class="headerlink" title="普通类的设计"></a>普通类的设计</h3><p> 假设原来有这样一个类:</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// File: Foo.h</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> {</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">Foo (<span class="keyword">int</span> data);</span><br><span class="line"><span class="keyword">virtual</span> ~Foo ();</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"><span class="keyword">int</span> data_;</span><br><span class="line">};</span><br></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// File: Foo.cpp</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"Foo.h"</span></span></span><br><span class="line"></span><br><span class="line">Foo::Foo(<span class="keyword">int</span> data) : data_(data) { }</span><br><span class="line">Foo::~Foo() { }</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">Foo::SetData</span><span class="params">(<span class="keyword">int</span> data)</span> </span>{</span><br><span class="line">data_ = data;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">Foo::Data</span><span class="params">()</span> </span>{</span><br><span class="line"><span class="keyword">return</span> data_;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="Pimpl模式"><a href="#Pimpl模式" class="headerlink" title="Pimpl模式"></a>Pimpl模式</h3><p>在Foo的基础上在抽象出一层接口:</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// File: Foo.h</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> {</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">Foo (<span class="keyword">int</span> data);</span><br><span class="line"><span class="keyword">virtual</span> ~Foo ();</span><br><span class="line"><span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">SetData</span><span class="params">(<span class="keyword">int</span> data)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">virtual</span> <span class="keyword">int</span> <span class="title">Data</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">FooImpl</span>;</span></span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">unique_ptr</span><FooImpl> foo_;</span><br><span class="line">};</span><br></pre></td></tr></table></figure><figure class="highlight plain"><figcaption><span>"Foo.h"</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">// File: Foo.cpp</span><br><span class="line">#include "Foo_impl.h"</span><br><span class="line"></span><br><span class="line">Foo::Foo(int data) {</span><br><span class="line">foo_ = std::make_unique<FooImpl> (data);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">Foo::~Foo() { }</span><br><span class="line"></span><br><span class="line">void Foo::SetData(int data) {</span><br><span class="line">foo_->SetData(data);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">int Foo::Data() {</span><br><span class="line">return foo_->Data();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// File: Foo_impl.h</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"Foo.h"</span></span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span>:</span>:FooImpl {</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">FooImpl (<span class="keyword">int</span> data);</span><br><span class="line"><span class="keyword">virtual</span> ~FooImpl ();</span><br><span class="line"><span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">SetData</span><span class="params">(<span class="keyword">int</span> data)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">virtual</span> <span class="keyword">int</span> <span class="title">Data</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"><span class="keyword">int</span> data_;</span><br><span class="line">};</span><br></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// File: Foo_impl.cpp</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"Foo.h"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"Foo_impl.h"</span></span></span><br><span class="line"></span><br><span class="line">Foo::FooImpl::FooImpl(<span class="keyword">int</span> data) : data_(data) { }</span><br><span class="line">Foo::FooImpl::~FooImpl() { }</span><br><span class="line"></span><br><span class="line"><span class="keyword">void</span> Foo::FooImpl::SetData(<span class="keyword">int</span> data) {</span><br><span class="line">data_ = data;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> Foo::FooImpl::Data() {</span><br><span class="line"><span class="keyword">return</span> data_;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="优缺点:"><a href="#优缺点:" class="headerlink" title="优缺点:"></a>优缺点:</h3><h4 id="优点:"><a href="#优点:" class="headerlink" title="优点:"></a>优点:</h4><ul><li>优化编译速度, 如上面的例子, 普通的实现方式,在设计类时不可避免要使用一些其他的类或者变量,就会引入很多头文件。那么在编译时,一个头文件的引入可能就会增加一杯咖啡的时间(例如windows.h), 而Pimpl不会, 因为其他模块在编译时只需要引入Foo.h头文件即可, 里面之后告诉编译器有个FooImpl的类, 没有很复杂的东西, 这时就不会引入很多的东西,编译时间就会短很多。</li><li>优化构建过程,无论我们怎么修改FooImpl, 只要Foo.h不变,那么就不会影响到使用的模块,编译时只需要编译FooImpl部分即可。</li><li>对具体实现的隐藏,模块输出对外接口时,头文件只会看到一个FooImpl的指针, 看不到类里面的内容。</li><li>对单元测试友好, 测试时只需要测试Impl部分即可, 因为Foo只是个接口。 如果测试另一个模块,Foo也可以加一个Only for Test的构造,来模拟真实的FooImpl, 避免过度耦合无法测试, 例如socket, 很多人喜欢在负责传输的模块内部直接写一个socket, 这样在测试时很难去模拟网络IO, 用Impl就很好的解决了这个问题。</li></ul><h4 id="缺点:"><a href="#缺点:" class="headerlink" title="缺点:"></a>缺点:</h4><ul><li>写起来更麻烦, 写的更多了, 但这好像不是什么太大的问题</li><li>增加开销, 因为多了一层调用</li><li>增加了内存的开销, 多了一个智能指针</li></ul><p>   </p><hr><p>参考:</p><p> Effective C++ & More Effective C++</p>]]></content>
<tags>
<tag> 编程 </tag>
</tags>
</entry>
<entry>
<title>GTest单元测试框架的基本使用</title>
<link href="29d24fe4/"/>
<url>29d24fe4/</url>
<content type="html"><![CDATA[<h2 id="GTest"><a href="#GTest" class="headerlink" title="GTest"></a>GTest</h2><blockquote><p>简介: google的单元测试框架</p></blockquote><h3 id="tl-dr"><a href="#tl-dr" class="headerlink" title="tl;dr"></a>tl;dr</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><gtest/gtest.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">add</span><span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> b)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">return</span> a+b;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">TEST(TestFun, Add) {</span><br><span class="line">EXPECT_EQ(add(<span class="number">1</span>, <span class="number">1</span>), <span class="number">2</span>);</span><br><span class="line">EXPECT_EQ(add(<span class="number">1</span>, <span class="number">2</span>), <span class="number">2</span>) << <span class="string">"add (1, 2) 应该是 "</span> << <span class="number">3</span> << <span class="string">"是的的结果是 "</span> << add(<span class="number">1</span>, <span class="number">2</span>);</span><br><span class="line">ASSERT_EQ(add(<span class="number">2</span>, <span class="number">2</span>), <span class="number">4</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>有一个被测试的方法, add, 通过TEST添加一个测试案例, 可以使用EXPECT和ASSERT两种宏, 实现测试值是否正确, 每个宏后面都可以跟上解释信息。 其中第二个很明显是错误的, 输出结果看下面。</p><p>编译命令<code>g++ file.cpp -lgtest -lgtest_main -lpthread -o main</code></p><p>其中用到了三个动态链接库, 第一个是gtest的库, 第二个是运行所有测试的实现, 其实里面就是写了个main函数, 也可以自己写,不连接这个库, 第三个是多线程库, 因为gtest使用了线程。</p><p>运行结果:</p><p><img src="/29d24fe4/1573372797119.png" alt="1573372797119"></p><p>可以看到失败的地方会有提示。</p><a id="more"></a><h3 id="基本使用"><a href="#基本使用" class="headerlink" title="基本使用"></a>基本使用</h3><ul><li><p>运行指定测试</p><p><code>--gtest_filter=TestName.*</code></p></li><li><p>测试案例宏</p><ul><li><p>TEST — 一个测试案例</p><p> 原型: TEST(TestCaseName, TestName) </p><blockquote><p>测试的逻辑是, 每个Case为一组, 组内可以有多个Test, 也就是说, 当测试一个类的时候, 可以这么写 Test(TestClassName, FuntionName)</p></blockquote></li><li><p>TEST_F</p><p>原型:TEST_F(TestFixtureName, TestName)</p><p>模具测试 当多个测试使用相同或类似的资源的时候, 可以使用模具进行测试, 需要创建模具类, 在里面创建需要的资源。</p><p>SetUp方法和TearDown方法在每次TEST_F执行之前和执行之后执行, 保证每次测试的资源都是没有关联的。</p><p><a href="#模具的使用">更多介绍请看模具的使用</a></p></li><li><p>TEST_P</p><p> //TODO:后续补充</p></li></ul></li><li><p>断言</p><ul><li><p>ASSERT_* – 当条件判断为假时, 不会往下继续执行</p><ul><li><p>ASSERT_EQ(val1, val2)</p><p> 断言val1和val2相等, 如果不相等会直接终止程序, 并报告错误, 信息里面有当前测试的案例和测试名称, 以及两个值分别是多少。</p><p> 甚至你可以添加一些输出, 让提示更加友好。</p><p> <code>ASSERT_EQ(v1, v2) << "v1 is not equal to v2 , v1 is " << v1 << " v2 is " << v2;</code></p><p> 这样当判断不相等是会输出后面的信息。</p></li></ul></li><li><p>EXPECT_* – 当条件为假时, 判为faile, 但是会继续向下执行</p><p> 用法与ASSERT一样, 唯一的区别就是如果断言值为假也会继续向下执行, 只是报告一个失败,下面的测试会继续进行。</p></li><li><p>同类的宏</p><p> 每个版本的宏都有两个,分别是EXPECT和ASSERT。 区别如上。</p><ul><li>大小值比较</li></ul><table><thead><tr><th>Fatal assertion</th><th>Nonfatal assertion</th><th>Verifies</th></tr></thead><tbody><tr><td><code>ASSERT_EQ(val1, val2);</code></td><td><code>EXPECT_EQ(val1, val2);</code></td><td><code>val1 == val2</code></td></tr><tr><td><code>ASSERT_NE(val1, val2);</code></td><td><code>EXPECT_NE(val1, val2);</code></td><td><code>val1 != val2</code></td></tr><tr><td><code>ASSERT_LT(val1, val2);</code></td><td><code>EXPECT_LT(val1, val2);</code></td><td><code>val1 < val2</code></td></tr><tr><td><code>ASSERT_LE(val1, val2);</code></td><td><code>EXPECT_LE(val1, val2);</code></td><td><code>val1 <= val2</code></td></tr><tr><td><code>ASSERT_GT(val1, val2);</code></td><td><code>EXPECT_GT(val1, val2);</code></td><td><code>val1 > val2</code></td></tr><tr><td><code>ASSERT_GE(val1, val2);</code></td><td><code>EXPECT_GE(val1, val2);</code></td><td><code>val1 >= val2</code></td></tr></tbody></table><ul><li><p>二进制值比较</p><table><thead><tr><th>Fatal assertion</th><th>Nonfatal assertion</th><th>Verifies</th></tr></thead><tbody><tr><td><code>ASSERT_TRUE(condition);</code></td><td><code>EXPECT_TRUE(condition);</code></td><td><code>condition</code> is true</td></tr><tr><td><code>ASSERT_FALSE(condition);</code></td><td><code>EXPECT_FALSE(condition);</code></td><td><code>condition</code> is false</td></tr></tbody></table></li><li><p>字符串比较</p><table><thead><tr><th>Fatal assertion</th><th>Nonfatal assertion</th><th>Verifies</th></tr></thead><tbody><tr><td><code>ASSERT_STREQ(str1,str2);</code></td><td><code>EXPECT_STREQ(str1,str2);</code></td><td>the two C strings have the same content</td></tr><tr><td><code>ASSERT_STRNE(str1,str2);</code></td><td><code>EXPECT_STRNE(str1,str2);</code></td><td>the two C strings have different contents</td></tr><tr><td><code>ASSERT_STRCASEEQ(str1,str2);</code></td><td><code>EXPECT_STRCASEEQ(str1,str2);</code></td><td>the two C strings have the same content, ignoring case</td></tr><tr><td><code>ASSERT_STRCASENE(str1,str2);</code></td><td><code>EXPECT_STRCASENE(str1,str2);</code></td><td>the two C strings have different contents, ignoring case</td></tr></tbody></table></li></ul></li></ul></li></ul><h3 id="模具的使用"><a href="#模具的使用" class="headerlink" title="模具的使用"></a>模具的使用</h3><blockquote><p>当多个测试使用的数据或对象相同时,可以创建一个模具给这一组测试使用。可以减少重复的代码。</p></blockquote><h3 id="使用步骤"><a href="#使用步骤" class="headerlink" title="使用步骤"></a>使用步骤</h3><ol><li>首先要创建一个模具类并继承<code>::testing::Test</code> </li><li>实现一个构造函数或者<code>Setup()</code>, 以及一个析构函数或者<code>TearDown()</code> </li><li>在构造函数或者<code>Setup()</code>方法里面创建一些测试需要的资源。 同理在析构或<code>TearDown</code>中释放这些资源。</li></ol><p>当使用模具进行测试的时候,使用<code>TEST_F</code> 替换<code>TEST</code>即可, 值得<strong>注意</strong>的是, 宏的第一个参数要改成自己写的模具类的名字。<code>TEST_F(TestFixtureName, TestName)</code> 即TestFixtureName要替换成模具类的名字。然后在函数体里面进行测试即可。</p><p> 对于每个测试(TEST_F), gtest都会在测试之前调用Setup为其创建测试环境, 当这个测试结束时会调用TearDown来清理现场。</p><ul><li><p>案例:</p> <figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><gtest/gtest.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><gmock/gmock.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> {</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">Foo (<span class="keyword">int</span> a = <span class="number">0</span>) {}</span><br><span class="line"><span class="keyword">virtual</span> ~Foo () {}</span><br><span class="line"><span class="function"><span class="keyword">virtual</span> <span class="keyword">int</span> <span class="title">getData</span><span class="params">()</span> </span>{ <span class="keyword">return</span> data_; }</span><br><span class="line"><span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">setData</span><span class="params">(<span class="keyword">int</span> data)</span> </span>{ data_ = data; }</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"><span class="keyword">int</span> data_;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">FooTest</span> :</span> <span class="keyword">public</span> ::testing::Test {</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">FooTest () { }</span><br><span class="line"><span class="keyword">virtual</span> ~FooTest () { }</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">SetUp</span><span class="params">()</span> </span>{</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"Before testing"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">foo_.setData(<span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">TearDown</span><span class="params">()</span> </span>{</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"After the test"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">protected</span>:</span><br><span class="line">Foo foo_;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line">TEST_F(FooTest, TestSetOne) {</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"TestSetOne start"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">EXPECT_EQ(foo_.getData(), <span class="number">1</span>) << <span class="string">"foo_ data is not equal to "</span> << <span class="number">1</span>;</span><br><span class="line"><span class="keyword">int</span> data = <span class="number">10</span>;</span><br><span class="line">foo_.setData(data);</span><br><span class="line">EXPECT_EQ(foo_.getData(), data) << <span class="string">"foo_ data is not equal to "</span> << data;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"TestSetOne end"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">TEST_F(FooTest, TestSetTwo) {</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"TestSetOne start"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">EXPECT_EQ(foo_.getData(), <span class="number">1</span>) << <span class="string">"foo_ data is not equal to "</span> << <span class="number">1</span>;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"TestSetOne end"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul><p><strong>结果:</strong></p><p><img src="/29d24fe4/1573959294258.png" alt="1573959294258"></p><p>如案例中所示, 在夹具中定义的资源可以在测试中直接使用,所以当多个测试使用的资源相同的时候,还有复杂的初始化工作的时候,就可以使用夹具,减少重复代码。</p><ul><li><p>SetUpCase 与 TearDownCase</p><p> TODO:后续补充</p></li></ul><p> </p><p> </p><h2 id="GMock"><a href="#GMock" class="headerlink" title="GMock"></a>GMock</h2><p><strong>简介:</strong> </p><p> 模拟类, 当我们写一个模块时,我们要依赖或使用另一个模块的接口或资源,例如数据库操作等。这时候另一个模块还没有写,我们需要测试一下现在写的模块功能是否正确,这就用到gmock了, 它可以模拟一个类, 可以指定一个行为,通过返回我们指定的数据来欺骗过我们写的模块。 例如我们需要数据库查询一个用户的信息,这时候可以模拟这个方法,直接返回一个固定的信息。</p><h3 id="Mock-Class"><a href="#Mock-Class" class="headerlink" title="Mock Class"></a>Mock Class</h3><p> 创建一个Mock类需要继承需要模拟的类或者接口。 使用MOCKMETHOD 模拟方法。</p><ul><li><p>MOCKMETHOD</p><p> MOCKMETHOD(返回值类型, 方法名, (参数), (override等))</p></li></ul><p> 写完一个模块需要单元测试时,依赖的另一个模块还没有做完,那么可以mock这个模块。例如 数据库模块。</p><p> </p><p> <br> <br> <br> <br> </p><h2 id="emsp"><a href="#emsp" class="headerlink" title=" "></a> </h2><p>参考连接:</p><ul><li>googletest仓库地址 <a href="https://github.com/google/googletest" target="_blank" rel="noopener">https://github.com/google/googletest</a> </li></ul>]]></content>
<categories>
<category> tool </category>
</categories>
<tags>
<tag> tool </tag>
<tag> gtest </tag>
<tag> gmock </tag>
<tag> 单元测试 </tag>
</tags>
</entry>
<entry>
<title>Hexo Commands</title>
<link href="b89ddfa7/"/>
<url>b89ddfa7/</url>
<content type="html"><![CDATA[<p> 摘要:</p><p> Hexo common commands </p><ul><li>init – init</li><li>new – new blog</li><li>generate – generate page</li><li>deploy – push to github</li><li>clean – clean</li><li>server – run locally</li></ul><a id="more"></a><h2 id="init"><a href="#init" class="headerlink" title="init"></a>init</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo init [folder]</span><br></pre></td></tr></table></figure><p>Initializes a website. If no <code>folder</code> is provided, Hexo will set up the website in the current directory.</p><h2 id="new"><a href="#new" class="headerlink" title="new"></a>new</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new [layout] <title></span><br></pre></td></tr></table></figure><p>Creates a new article. If no <code>layout</code> is provided, Hexo will use the <code>default_layout</code> from <a href="https://hexo.io/docs/configuration" target="_blank" rel="noopener">_config.yml</a>. If the <code>title</code> contains spaces, surround it with quotation marks.</p><table><thead><tr><th align="left">Option</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><code>-p</code>, <code>--path</code></td><td align="left">Post path. Customize the path of the post.</td></tr><tr><td align="left"><code>-r</code>, <code>--replace</code></td><td align="left">Replace the current post if existed.</td></tr><tr><td align="left"><code>-s</code>, <code>--slug</code></td><td align="left">Post slug. Customize the URL of the post.</td></tr></tbody></table><p>By default, Hexo will use the title to define the path of the file. For pages, it will create a directory of that name and an <code>index.md</code> file in it. Use the <code>--path</code> option to override that behaviour and define the file path:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo new page --path about/me "About me"</span><br></pre></td></tr></table></figure><p>will create <code>source/about/me.md</code> file with the title “About me” set in the front matter.</p><p>Please note that the title is mandatory. For example, this will not result in the behaviour you might expect:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo new page --path about/me</span><br></pre></td></tr></table></figure><p>will create the post <code>source/_posts/about/me.md</code> with the title “page” in the front matter. This is because there is only one argument (<code>page</code>) and the default layout is <code>post</code>.</p><h2 id="generate"><a href="#generate" class="headerlink" title="generate"></a>generate</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure><p>Generates static files.</p><table><thead><tr><th align="left">Option</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><code>-d</code>, <code>--deploy</code></td><td align="left">Deploy after generation finishes</td></tr><tr><td align="left"><code>-w</code>, <code>--watch</code></td><td align="left">Watch file changes</td></tr><tr><td align="left"><code>-b</code>, <code>--bail</code></td><td align="left">Raise an error if any unhandled exception is thrown during generation</td></tr><tr><td align="left"><code>-f</code>, <code>--force</code></td><td align="left">Force regenerate</td></tr></tbody></table><h2 id="publish"><a href="#publish" class="headerlink" title="publish"></a>publish</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo publish [layout] <filename></span><br></pre></td></tr></table></figure><p>Publishes a draft.</p><h2 id="server"><a href="#server" class="headerlink" title="server"></a>server</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure><p>Starts a local server. By default, this is at <code>http://localhost:4000/</code>.</p><table><thead><tr><th align="left">Option</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><code>-p</code>, <code>--port</code></td><td align="left">Override default port</td></tr><tr><td align="left"><code>-s</code>, <code>--static</code></td><td align="left">Only serve static files</td></tr><tr><td align="left"><code>-l</code>, <code>--log</code></td><td align="left">Enable logger. Override logger format.</td></tr></tbody></table><h2 id="deploy"><a href="#deploy" class="headerlink" title="deploy"></a>deploy</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure><p>Deploys your website.</p><table><thead><tr><th align="left">Option</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><code>-g</code>, <code>--generate</code></td><td align="left">Generate before deployment</td></tr></tbody></table><h2 id="render"><a href="#render" class="headerlink" title="render"></a>render</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo render <file1> [file2] ...</span><br></pre></td></tr></table></figure><p>Renders files.</p><table><thead><tr><th align="left">Option</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><code>-o</code>, <code>--output</code></td><td align="left">Output destination</td></tr></tbody></table><h2 id="migrate"><a href="#migrate" class="headerlink" title="migrate"></a>migrate</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo migrate <type></span><br></pre></td></tr></table></figure><p>Migrates content from other blog systems.</p><h2 id="clean"><a href="#clean" class="headerlink" title="clean"></a>clean</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo clean</span><br></pre></td></tr></table></figure><p>Cleans the cache file (<code>db.json</code>) and generated files (<code>public</code>).</p><h2 id="list"><a href="#list" class="headerlink" title="list"></a>list</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo list <type></span><br></pre></td></tr></table></figure><p>Lists all routes.</p><h2 id="version"><a href="#version" class="headerlink" title="version"></a>version</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo version</span><br></pre></td></tr></table></figure><p>Displays version information.</p><h2 id="Options"><a href="#Options" class="headerlink" title="Options"></a>Options</h2><h3 id="Safe-mode"><a href="#Safe-mode" class="headerlink" title="Safe mode"></a>Safe mode</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo --safe</span><br></pre></td></tr></table></figure><p>Disables loading plugins and scripts. Try this if you encounter problems after installing a new plugin.</p><h3 id="Debug-mode"><a href="#Debug-mode" class="headerlink" title="Debug mode"></a>Debug mode</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo --debug</span><br></pre></td></tr></table></figure><p>Logs verbose messages to the terminal and to <code>debug.log</code>. Try this if you encounter any problems with Hexo. If you see errors, please <a href="https://github.com/hexojs/hexo/issues/new" target="_blank" rel="noopener">raise a GitHub issue</a>.</p><h3 id="Silent-mode"><a href="#Silent-mode" class="headerlink" title="Silent mode"></a>Silent mode</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo --silent</span><br></pre></td></tr></table></figure><p>Silences output to the terminal.</p><h3 id="Customize-config-file-path"><a href="#Customize-config-file-path" class="headerlink" title="Customize config file path"></a>Customize config file path</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo --config custom.yml</span><br></pre></td></tr></table></figure><p>Uses a custom config file (instead of <code>_config.yml</code>). Also accepts a comma-separated list (no spaces) of JSON or YAML config files that will combine the files into a single <code>_multiconfig.yml</code>.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo --config custom.yml,custom2.json</span><br></pre></td></tr></table></figure><h3 id="Display-drafts"><a href="#Display-drafts" class="headerlink" title="Display drafts"></a>Display drafts</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo --draft</span><br></pre></td></tr></table></figure><p>Displays draft posts (stored in the <code>source/_drafts</code> folder).</p><h3 id="Customize-CWD"><a href="#Customize-CWD" class="headerlink" title="Customize CWD"></a>Customize CWD</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo --cwd /path/to/cwd</span><br></pre></td></tr></table></figure><p>Customizes the path of current working directory.</p>]]></content>
<categories>
<category> tool </category>
</categories>
<tags>
<tag> tool </tag>
<tag> Hexo </tag>
</tags>
</entry>
<entry>
<title>Linux常用技巧</title>
<link href="7776412d/"/>
<url>7776412d/</url>
<content type="html"><![CDATA[<p>摘要:</p><p> 在Linux下的一些常用的命令, 例如:</p><pre><code>- 快捷键- whatis- 文件操作- 磁盘操作等 - 进程等</code></pre><a id="more"></a><h2 id="一-终端快捷键"><a href="#一-终端快捷键" class="headerlink" title="一. 终端快捷键"></a>一. 终端快捷键</h2><h2 id="二-简单命令的使用"><a href="#二-简单命令的使用" class="headerlink" title="二. 简单命令的使用"></a>二. 简单命令的使用</h2><h3 id="2-1-帮助类命令"><a href="#2-1-帮助类命令" class="headerlink" title="2.1 帮助类命令"></a>2.1 帮助类命令</h3><ul><li><p><code>whatis</code> 查看命令的简要说明</p><ul><li>基本使用<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">whatis command</span><br></pre></td></tr></table></figure></li></ul></li><li><p>正则匹配</p><pre><code><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">whatis -w "loca*"</span><br></pre></td></tr></table></figure></code></pre></li><li><p><code>man</code> 说明文档</p><ul><li><p>基本使用 </p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">man command</span><br></pre></td></tr></table></figure></li><li><p>man 手册的分类</p><p> 使用方式 <code>man [1-9] command</code></p><p> (1)、用户可以操作的命令或者是可执行文件<br> (2)、系统核心可调用的函数与工具等<br> (3)、一些常用的函数与数据库<br> (4)、设备文件的说明<br> (5)、设置文件或者某些文件的格式<br> (6)、游戏<br> (7)、惯例与协议等。例如Linux标准文件系统、网络协议、ASCⅡ,码等说明内容<br> (8)、系统管理员可用的管理条令<br> (9)、与内核有关的文件</p></li></ul></li><li><p><code>which / whereis</code> 查看路径</p><ul><li><p>查找二进制文件的路径 <em>需要在path路径中</em></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">which command</span><br></pre></td></tr></table></figure></li><li><p>查看程序的搜索路径</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">whereis command</span><br></pre></td></tr></table></figure></li></ul></li></ul><h3 id="2-2-文件及目录管理"><a href="#2-2-文件及目录管理" class="headerlink" title="2.2 文件及目录管理"></a>2.2 文件及目录管理</h3><ul><li><p>基本命令</p><ul><li>touch、 mkdir 创建文件或文件夹</li><li>rm 、 rmdir 删除文件或文件夹, rm -rf 也可以删除文件夹</li><li>mv 移动</li><li>cd 切换目录</li><li>cp 复制</li><li>pwd 显示当前路径</li><li>chmod 更改权限</li><li>chown 更改所有者</li><li>chgrp 更改所属组</li></ul><blockquote><p>其中都可以加参数, 一般常用的参数为 -r 递归, -f 强制 -v 提示 </p><p>也可以使用通配符, *表示匹配任意字符任意个数</p></blockquote></li><li><p>文件查找</p><ul><li><p><code>find</code> 实施搜索文件或目录</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">find ./ -name "filename*"</span><br></pre></td></tr></table></figure><p> <strong>常用参数:</strong></p><ul><li><p><code>-name</code> 查找文件名</p></li><li><p><code>-maxdepth n</code> 查找最大深度 n</p><p> <code>find . -maxdepth 1 -name "filename"</code> </p></li><li><p><code>-regex</code> 按正则方式匹配</p><p> <code>find . -regex ".*\(\.txt\|\.pdf\)$"</code> 查找txt或pdf文件</p></li><li><p><code>-type</code> 按类型搜索, 常用的 d 文件夹, f 文件</p></li><li><p><code>-atime +-n</code> +n表示七天前被访问过的, -n表示七天内被访问过的。 n表示第七天被访问过的。 </p></li><li><p><code>-size +-n</code> +2k表示大于2K的文件, 支持的单位有 k M G</p></li><li><p><code>-delete</code> 找到后删除</p></li><li><p>执行动作 <code>find . -name "*.swp" -exec rm {} \;</code> </p></li></ul></li><li><p><code>locate</code> 使用文件系统索引搜索</p><p> <code>locate filename</code></p><p> 使用 <code>updatedb</code> 更新数据库, 以获得最新的索引</p></li></ul></li><li><p>查看文件内容</p><blockquote><p>可使用的工具有 cat vi head tail more等</p></blockquote><ul><li><p><code>cat</code> 链接文件并输出到标准输出</p><p> cat 会把传入的文件都连起来,并输出到标准输出</p><p> <code>cat file1 file2</code> 会把file1 和 file2的内容连接起来一块输出到控制台</p><p> <strong>常用参数:</strong></p><ul><li><code>-n</code> 显示行号</li><li><code>-b</code> 显示行号, 但不计算空行的行号, 这个参数会覆盖<code>-n</code></li></ul></li><li><p><code>more</code> 按页显示列表内容</p><p> <code>ls -al | more</code></p></li><li><p><code>head</code> 从头查看内容</p><p> <code>head -10 file</code> 查看file的前十行</p></li><li><p><code>tail -5 file</code> 显示file的后五行</p><p> <strong>常用参数:</strong></p><ul><li><code>-f</code> 动态显示文本最新信息</li></ul></li><li><p><code>diff file1 file2</code> 显示两个文件的差异</p></li></ul></li><li><p>文件链接 (快捷方式或别名)</p><ul><li><p><code>ln</code> </p><p> <strong>常用参数:</strong></p><ul><li><p>默认创建硬连接, 删除其中一个, 另一个仍然能使用</p></li><li><p><code>-s</code> 创建软连接, 删除了源文件,则软连接失效, 删除软连接,源文件不影响。</p><blockquote><p>硬连接不能跨硬盘, 软连接可以</p></blockquote></li></ul></li></ul></li><li><p>管道与重定向</p><ul><li><p>连接执行 <code>|</code></p><p> <code>ls -al | more</code></p></li><li><p>串联 <code>;</code> </p><p> <code>if ls /proc; then echo suss; else echo fail; fi</code></p></li><li><p>前面失败,则执行后一条 <code>||</code></p><p> <code>ls /proc && echo suss! || echo failed.</code> 与上一条效果相同</p></li><li><p>前面失败,不执行 <code>&&</code></p><p> <code>proc1 && proc2</code></p></li><li><p>重定向</p><p> <code>ls proc/*.c &> list</code> 将错误和标准输出重定向的list文件</p><p> <code>:> a.txt</code> 清空a.txt文件</p><p> <code>echo a >> a.txt</code> 重定向到a.txt</p></li></ul></li></ul><h3 id="2-3-文本处理"><a href="#2-3-文本处理" class="headerlink" title="2.3 文本处理"></a>2.3 文本处理</h3><h2 id="三-Linux工具"><a href="#三-Linux工具" class="headerlink" title="三. Linux工具"></a>三. Linux工具</h2>]]></content>
<categories>
<category> Linux基础 </category>
</categories>
<tags>
<tag> tool </tag>
<tag> Linux </tag>
</tags>
</entry>
<entry>
<title>hexo插入图片无法显示的问题</title>
<link href="dbf3a70c/"/>
<url>dbf3a70c/</url>
<content type="html"><![CDATA[<p> hexo上的图片无法显示的原因是hexo-asset-image插件有个bug, 解决一处错误之后就可以显示图片了。</p><a id="more"></a><h3 id="安装的插件"><a href="#安装的插件" class="headerlink" title="安装的插件"></a>安装的插件</h3><blockquote><p>注意: </p><p> hexo显示图片需要插件, 如果没有安装插件,请先安装插件。</p><p> 如果只是解决错误无需安装插件, 这里只是说明我使用的插件是否跟你的一样。如果不是这个插件就没必要浪费时间往下读了。</p></blockquote><ul><li>安装了插入图片的插件 <code>npm install hexo-asset-image --save</code></li><li><code>_config.yml</code> 里的<code>post_asset_folder:</code>这个选项设置为<code>true</code></li></ul><h3 id="发现问题"><a href="#发现问题" class="headerlink" title="发现问题"></a>发现问题</h3><blockquote><p>注意: 下面啰嗦了很多,叙述了过程, 如果没兴趣可以直接看最后结论。</p></blockquote><p>然额…… 为什么图片依然显示不出来</p><ul><li>找到:public下面对应的html, 打开一看… <code><img src="/.com//20180209124830981.png" alt="img"></code></li></ul><p>???.jpg</p><p>路径怎么不对, 哪有个.com目录, 不是应该 <code>.com/2019/09/12/hexo插入图片无法显示的问题/20180209124830981.png</code>吗</p><p>没办法只能上网上搜一下,结果好多说路径有问题的, 原来是这个插件的问题,那么debug吧, 谁让我是个程序猿呢。</p><p>hexo-asset-image插件在 <code>/yourPath/node_modules/hexo-asset-image</code>下面, index.js就是主要代码。</p><p><strong>注意:</strong> yourPath是你的blog路径。 即存在<code>_config.yml</code>文件的路径(不是主题下面的那个)。</p><p>index.js 文件中有这样几行代码。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> link = data.permalink;</span><br><span class="line"><span class="keyword">var</span> beginPos = getPosition(link, <span class="string">'/'</span>, <span class="number">3</span>) + <span class="number">1</span>;</span><br><span class="line"><span class="keyword">var</span> appendLink = <span class="string">''</span>;</span><br><span class="line"><span class="comment">// In hexo 3.1.1, the permalink of "about" page is like ".../about/index.html".</span></span><br><span class="line"><span class="comment">// if not with index.html endpos = link.lastIndexOf('.') + 1 support hexo-abbrlink</span></span><br><span class="line"><span class="keyword">if</span>(<span class="regexp">/.*\/index\.html$/</span>.test(link)) {</span><br><span class="line"> <span class="comment">// when permalink is end with index.html, for example 2019/02/20/xxtitle/index.html</span></span><br><span class="line"> <span class="comment">// image in xxtitle/ will go to xxtitle/index/</span></span><br><span class="line"> appendLink = <span class="string">'index/'</span>;</span><br><span class="line"> <span class="keyword">var</span> endPos = link.lastIndexOf(<span class="string">'/'</span>);</span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">var</span> endPos = link.lastIndexOf(<span class="string">'.'</span>);</span><br><span class="line">}</span><br><span class="line">link = link.substring(beginPos, endPos) + <span class="string">'/'</span> + appendLink;</span><br></pre></td></tr></table></figure><p>打印一下 一开始的link发现, 是你文章的html的路径,<code>http://yoursite.com/2019/09/12/hexo插入图片无法显示的问题/</code></p><p>其中……就是文件的路径。 那么只要拿到这个路径,就找到了图片的路径, 因为hexo会把你的图片复制到生成html的同一个目录。</p><p>那么第三行的代码找到的beginPos就是找到的路径开始的位置。 逻辑没有问题啊。 继续找吧。</p><p>问题来了。 后面的if 说判断如果是index.html结尾的话, 就会把图片复制到index目录。 否则的话就复制到当前目录。 </p><p>但是 var endPos = link.lastIndexOf(‘/‘); 找到的是哪个 这不是斜杠吗, 而且不是index.html结尾的话, 找到.到哪里了,一看可不就是.com吗, 可找到.com哪里来的了。 </p><p>很明显, 这两句写反了。 换过来就ok啦。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(<span class="regexp">/.*\/index\.html$/</span>.test(link)) {</span><br><span class="line"> <span class="comment">// when permalink is end with index.html, for example 2019/02/20/xxtitle/index.html</span></span><br><span class="line"> <span class="comment">// image in xxtitle/ will go to xxtitle/index/</span></span><br><span class="line"> appendLink = <span class="string">'index/'</span>;</span><br><span class="line"> <span class="keyword">var</span> endPos = link.lastIndexOf(<span class="string">'.'</span>);</span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">var</span> endPos = link.lastIndexOf(<span class="string">'/'</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p> </p><p> </p><p> </p><h3 id="给没看懂的人的解决方法:"><a href="#给没看懂的人的解决方法:" class="headerlink" title="给没看懂的人的解决方法:"></a>给没看懂的人的解决方法:</h3><p>找到<code>node_modules/hexo-asset-image/index.js</code>文件, 找到一个代码段</p><p><img src="/dbf3a70c/1575104682904.png" alt="1575104682904"></p><p>将两行互换即可。</p>]]></content>
<categories>
<category> other </category>
</categories>
<tags>
<tag> hexo </tag>
</tags>
</entry>
<entry>
<title>Protobuf3简单使用及Demo</title>
<link href="f274fc39/"/>
<url>f274fc39/</url>
<content type="html"><![CDATA[<p>摘要:</p><p> 一个二进制协议, 可以兼容多种语言。</p><a id="more"></a><h3 id="Protobuf简介"><a href="#Protobuf简介" class="headerlink" title="Protobuf简介"></a>Protobuf简介</h3><blockquote><pre><code>简单设计协议, 通过自带工具转换成为对应的语言代码, 协议是二进制协议, 设计时只需要描述各个类的关系, 简单明了</code></pre></blockquote><h3 id="用法:"><a href="#用法:" class="headerlink" title="用法:"></a>用法:</h3><ul><li>设计协议是在fileName.proto文件中, 其中fileName是自己定义, 在通过protoc转换成为对应的代码。</li></ul><ul><li><p>关键字:</p><ul><li>message 表示一个消息体, 相当于一个类。</li><li>每个message中都有对应的变量, 每个变量有个对应的编号, 每个message内不同变量的编号不能重复。</li><li>新版本的protobuf没有了required, optional等说明关键字, 都默认为optional</li></ul></li><li><p>基本语法</p> <figure class="highlight protobuf"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//指定版本 使用protobuf3</span></span><br><span class="line">syntax = <span class="string">"proto3"</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">message</span> <span class="title">Account</span> </span>{</span><br><span class="line"><span class="comment">//账号</span></span><br><span class="line"><span class="built_in">uint64</span> ID = <span class="number">1</span>;</span><br><span class="line"><span class="comment">//名字</span></span><br><span class="line"><span class="built_in">string</span> name = <span class="number">2</span>;</span><br><span class="line"><span class="comment">//密码</span></span><br><span class="line"><span class="built_in">string</span> password = <span class="number">3</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><pre><code>语法很简单, 上面例子就是指定使用protob3, 然后定义了一个Account类, 里面包含ID, name, password, 对应的类型是 uint64, string, string。所以基本的语法规则跟C++类似。 只不过多了后面变量的编号。</code></pre></li><li><p>生成代码:</p><p> 需要生成什么语言的代码需要直接指定,例如C++</p><p> <code>protoc --cpp_out=./ project.proto</code></p><p> <code>protoc</code>是工具名, 可以直接运行的命令。</p><p> <code>--cpp_out</code>是参数, 指定生成C++代码, =后面指定生成的目录。</p><p> <code>project.proto</code>是定义的文件。</p><p> 一共会生成两个文件。 <code>project.pb.h</code> 和 <code>project.pb.cc</code></p><p> 其中有生成的Account类中有这几个设置属性的方法</p> <figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">clear_name</span><span class="params">()</span></span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">int</span> kNameFieldNumber = <span class="number">2</span>;</span><br><span class="line"><span class="function"><span class="keyword">const</span> <span class="built_in">std</span>::<span class="built_in">string</span>& <span class="title">name</span><span class="params">()</span> <span class="keyword">const</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">set_name</span><span class="params">(<span class="keyword">const</span> <span class="built_in">std</span>::<span class="built_in">string</span>& value)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">set_name</span><span class="params">(<span class="built_in">std</span>::<span class="built_in">string</span>&& value)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">set_name</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span>* value)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">set_name</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span>* value, <span class="keyword">size_t</span> <span class="built_in">size</span>)</span></span>;</span><br><span class="line"><span class="function"><span class="built_in">std</span>::<span class="built_in">string</span>* <span class="title">mutable_name</span><span class="params">()</span></span>;</span><br><span class="line"><span class="function"><span class="built_in">std</span>::<span class="built_in">string</span>* <span class="title">release_name</span><span class="params">()</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">set_allocated_name</span><span class="params">(<span class="built_in">std</span>::<span class="built_in">string</span>* name)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// string password = 3;</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">clear_password</span><span class="params">()</span></span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">int</span> kPasswordFieldNumber = <span class="number">3</span>;</span><br><span class="line"><span class="function"><span class="keyword">const</span> <span class="built_in">std</span>::<span class="built_in">string</span>& <span class="title">password</span><span class="params">()</span> <span class="keyword">const</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">set_password</span><span class="params">(<span class="keyword">const</span> <span class="built_in">std</span>::<span class="built_in">string</span>& value)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">set_password</span><span class="params">(<span class="built_in">std</span>::<span class="built_in">string</span>&& value)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">set_password</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span>* value)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">set_password</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span>* value, <span class="keyword">size_t</span> <span class="built_in">size</span>)</span></span>;</span><br><span class="line"><span class="function"><span class="built_in">std</span>::<span class="built_in">string</span>* <span class="title">mutable_password</span><span class="params">()</span></span>;</span><br><span class="line"><span class="function"><span class="built_in">std</span>::<span class="built_in">string</span>* <span class="title">release_password</span><span class="params">()</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">set_allocated_password</span><span class="params">(<span class="built_in">std</span>::<span class="built_in">string</span>* password)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// uint64 ID = 1;</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">clear_id</span><span class="params">()</span></span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">int</span> kIDFieldNumber = <span class="number">1</span>;</span><br><span class="line">::<span class="function">PROTOBUF_NAMESPACE_ID::uint64 <span class="title">id</span><span class="params">()</span> <span class="keyword">const</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">set_id</span><span class="params">(::PROTOBUF_NAMESPACE_ID::uint64 value)</span></span>;</span><br></pre></td></tr></table></figure><p> 及get/set方法。</p><p> 可以直接操作该类的属性。</p></li><li><p>使用该代码</p><ul><li><p>在要使用的代码中包含此头文件<code>project.pb.h</code></p><p> 直接使用该对象即可。编译的时候需要把<code>project.pb.cc</code>编译, 并在链接的时候链接动态链接库 <code>libprotobuf.so</code></p></li></ul></li><li><p>demo</p> <figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><string></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"project.pb.h"</span></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">Account account;</span><br><span class="line">account.set_id(<span class="number">1000</span>);</span><br><span class="line">account.set_name(<span class="string">"name"</span>);</span><br><span class="line">account.set_password(<span class="string">"password"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//序列化</span></span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">string</span> s = account.SerializeAsString();</span><br><span class="line"><span class="keyword">if</span>(s.<span class="built_in">size</span>() == <span class="number">0</span>) {</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"error in SerializeAsString"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">}</span><br><span class="line">Account nAccount;</span><br><span class="line"> <span class="comment">//反序列化</span></span><br><span class="line"><span class="keyword">if</span>(nAccount.ParseFromString(s)) {</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> << nAccount.id() << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> << nAccount.name() << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> << nAccount.password() << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"error in ParseFromString"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>编译</p><p> <code>project.pb.cc</code>也需要编译, 如果是工程中, 可以单独编译, 由于只有一个文件所以就放到一块编译了<code>g++ demo.cpp project.pb.cc -lprotobuf -o main</code></p><p> 输出结果为:</p><blockquote><p>1000 </p><p>name </p><p>password</p></blockquote></li></ul><h3 id="更复杂的demo"><a href="#更复杂的demo" class="headerlink" title="更复杂的demo"></a>更复杂的demo</h3><ul><li><p>message的嵌套</p><blockquote><p>message就像类一样, 所以它也是可以嵌套的。</p><p>可以直接在message内写, 也可以在外部写, 但是要注意的是, 一个message内的编号不能重复。</p><p>所以令写一个message会节省编号。</p><p>节省编号的所有是节省空间。 前15号(0~15)用一个字节, 后面以此类推, 两个三个字节, 所以前15编号比较珍贵。</p></blockquote></li><li><p>demo</p> <figure class="highlight protobuf"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//指定版本 使用protobuf3</span></span><br><span class="line">syntax = <span class="string">"proto3"</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">message</span> <span class="title">Account</span> </span>{</span><br><span class="line"><span class="comment">//账号</span></span><br><span class="line"><span class="built_in">uint64</span> ID = <span class="number">1</span>;</span><br><span class="line"><span class="comment">//名字</span></span><br><span class="line"><span class="built_in">string</span> name = <span class="number">2</span>;</span><br><span class="line"><span class="comment">//密码</span></span><br><span class="line"><span class="built_in">string</span> password = <span class="number">3</span>;</span><br><span class="line"><span class="comment">//宠物狗</span></span><br><span class="line">Dog dog = <span class="number">4</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">message</span> <span class="title">Dog</span> </span>{</span><br><span class="line"><span class="built_in">string</span> name = <span class="number">0</span>;</span><br><span class="line"><span class="built_in">bool</span> sex = <span class="number">1</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p> 还有几个比较重要的方法</p><p> <code>set_allocated_dog</code> dog不是必须的, 是类的名字。 可以是其他的名字</p><ul><li><p>参数是一个对应类型的指针, 调用这个函数, 它会自动释放这个指针的对象, 所以不需要delete, 否则会段错误。</p></li><li><p>再次调用这个参数时, 如果之前已经设置过参数, 那么再次调用的时候会之前设置的属性删除, 并且delete越来的对象。 在设置成新的属性。</p><p>除了这些方法之外还有一些clear之类的方法, 需要可以看文档或者给的头文件。</p></li></ul></li></ul><h3 id="oneof"><a href="#oneof" class="headerlink" title="oneof"></a>oneof</h3><blockquote><p>oneof 是设置多个属性中的一个, 例如, 我的宠物可以是狗, 也可以是猫, 但是每个人只有一个的话。 设置两个占的空间就有点大。 因此只需要有一个就够了, 所以这个oneof就像union一样。</p></blockquote><figure class="highlight protobuf"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//指定版本 使用protobuf3</span></span><br><span class="line">syntax = <span class="string">"proto3"</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">message</span> <span class="title">Account</span> </span>{</span><br><span class="line"><span class="comment">//账号</span></span><br><span class="line"><span class="built_in">uint64</span> ID = <span class="number">1</span>;</span><br><span class="line"><span class="comment">//名字</span></span><br><span class="line"><span class="built_in">string</span> name = <span class="number">2</span>;</span><br><span class="line"><span class="comment">//密码</span></span><br><span class="line"><span class="built_in">string</span> password = <span class="number">3</span>;</span><br><span class="line"><span class="comment">//宠物</span></span><br><span class="line"><span class="keyword">oneof</span> pet {</span><br><span class="line">Dog dog = <span class="number">4</span>;</span><br><span class="line">Cat cat = <span class="number">5</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">message</span> <span class="title">Dog</span> </span>{</span><br><span class="line"><span class="built_in">string</span> name = <span class="number">1</span>;</span><br><span class="line"><span class="built_in">bool</span> sex = <span class="number">2</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">message</span> <span class="title">Cat</span> </span>{</span><br><span class="line"><span class="built_in">string</span> name = <span class="number">1</span>;</span><br><span class="line"><span class="comment">//属性可以与Dog不同</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>方法<ul><li><code>has_cat</code> 或者 <code>has_dog</code> 方法用于检测是否有cat/dog</li><li>添加cat和dog直接用原来的方法添加即可。 但是当添加dog的时候会自动删除cat, 反之亦然。</li></ul></li></ul>]]></content>
<categories>
<category> C++ </category>
</categories>
<tags>
<tag> tool </tag>
<tag> protbuf </tag>
</tags>
</entry>
<entry>
<title>CMake入门和CMake外部构建</title>
<link href="f9c5a82d/"/>
<url>f9c5a82d/</url>
<content type="html"><![CDATA[<p>摘要:</p><p> CMake的基本使用</p><p> 适用CMake在外部构建, 防止污染工作目录</p><a id="more"></a><h2 id="CMake"><a href="#CMake" class="headerlink" title="CMake"></a>CMake</h2><h4 id="基本命令"><a href="#基本命令" class="headerlink" title="基本命令"></a>基本命令</h4><blockquote><p>每个目录下需要有CMakeLists.txt, 解释如何构建</p></blockquote><ul><li><p>指定CMake最低版本号要求<br> <code>cmake_minimum_required(VERSION 2.8)</code></p></li><li><p>指定项目名称</p><p> <code>project(projectName)</code></p></li><li><p>指定生成目标</p><p> <code>add_executable(Demo fileList...)</code></p><p> 例如 <code>add_executable(main main.cpp)</code></p><p> 多个文件时只需要在fileList处罗列即可, 空格隔开每个文件名, Demo则是生成的可执行文件名称</p></li><li><p>执行CMake</p><p> <code># cmake .</code> .表示当前目录</p></li><li><p>查找指定文件夹下所有的文件</p><p> <code>aux_source_directory(<dir> <variable>)</code></p><blockquote><p>将dir下所有文件名赋值为variable变量, 每个变量名用空格隔开</p></blockquote></li><li><p>添加头文件路径</p><p> <code>include_directories("path")</code></p></li></ul><h4 id="多级目录"><a href="#多级目录" class="headerlink" title="多级目录"></a>多级目录</h4><blockquote><p>多个目录时, 每个目录下面都要有CMakeLists.txt文件</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">./Demo</span><br><span class="line"> |</span><br><span class="line"> +--- main.cc</span><br><span class="line"> |</span><br><span class="line"> +--- math/</span><br><span class="line"> |</span><br><span class="line"> +--- MathFunctions.cc</span><br><span class="line"> |</span><br><span class="line"> +--- MathFunctions.h</span><br></pre></td></tr></table></figure><p>对于这种情况: 将math下的代码生成静态链接库</p><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">aux_source_directory</span>(. DIR_LIB_SRCS)</span><br><span class="line"><span class="comment"># 生成链接库</span></span><br><span class="line"><span class="keyword">add_library</span> (MathFunctions <span class="variable">${DIR_LIB_SRCS}</span>)</span><br></pre></td></tr></table></figure><p>Demo文件夹下:</p><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">project</span>(Demo)</span><br><span class="line"></span><br><span class="line">aux_source_ddirectory(. DIR_SRC)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加 math 子目录</span></span><br><span class="line"><span class="keyword">add_subdirectory</span>(<span class="keyword">math</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">add_executable</span>(Demo main.cc)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加链接库</span></span><br><span class="line"><span class="keyword">target_link_libraries</span>(Demo MathFunctions)</span><br></pre></td></tr></table></figure><p>这样即可多级目录构建</p><h4 id="外部构建"><a href="#外部构建" class="headerlink" title="外部构建"></a>外部构建</h4><blockquote><pre><code>使用cmake . 的是后总是在当前目录生成很多文件和文件夹, 目前来说这些除了Makefile都是没用的,看起来很闹心 。如果可以让生成的文件放到一个固定的目录就好了。也就是官方推荐的外部构建(out-of-source), 最大的好处是不会再原来的目录下生成与工程无关的文件。</code></pre></blockquote><p>外部构建的方法很简单,一开始使用<code>cmake .</code>的时候这个<code>.</code>表示的是当前目录,那么如果在别的地方,时候cmake命令构建的时候只要给定一个正确的路径就可以了,例如在当前工程目录下创建一个<code>build</code>目录,进入build目录, 然后使用<code>cmake ..</code>即可构建。这样生成的文件就在当前目录下了。</p><h4 id="自定义编译选项"><a href="#自定义编译选项" class="headerlink" title="自定义编译选项"></a>自定义编译选项</h4><blockquote><p>后续用的话再更新, 现在刚开始还用不到。</p></blockquote>]]></content>
<categories>
<category> tool </category>
</categories>
<tags>
<tag> tool </tag>
</tags>
</entry>
<entry>
<title>Linux进程内存分布</title>
<link href="c284c665/"/>
<url>c284c665/</url>
<content type="html"><![CDATA[<p> 在多任务操作系统中, 每个进程都有自己的内存沙盘, 使用的内存地址都是自己内存中的相对地址,当CPU时间片轮转到的时候, 操作系统将对应进程的内存页调入寄存器, 进程开始运行。因此不同进程间的内存地址是没有关联的, 都是自己的相对地址。</p><a id="more"></a><h4 id="内存分布图"><a href="#内存分布图" class="headerlink" title="内存分布图"></a>内存分布图</h4><p><img src="/c284c665/041752323799167.jpg" alt="在这里插入图片描述"></p><p>这个图是32位机器的, $2^{32} = 4GB$, 64位机器就有点大了, $(4GB)^2$ 额…… 反正你用不到这么大就行了。 分配比例差不多吧, 不是很了解。</p><h4 id="概要:"><a href="#概要:" class="headerlink" title="概要:"></a>概要:</h4><blockquote><p>这图上部是高地址, 最下面是0, 共分为两部分, 内核区和用户区</p></blockquote><h4 id="内核区:"><a href="#内核区:" class="headerlink" title="内核区:"></a>内核区:</h4><p>内核区不允许用户代码访问, 只要访问就会出现段错误, 内核区主要有PCB(进程控制块), 保存进程运行的信息</p><h4 id="栈区:"><a href="#栈区:" class="headerlink" title="栈区:"></a>栈区:</h4><p>保存的内容:</p><ul><li><p>函数内定义的局部变量(非static)</p></li><li><p>中断发生时存放的运行环境 </p></li></ul><p> 用户区第一块区域,当函数结束时, 局部变量自动销毁, 内存自动释放, 因此这部分内存不需要程序员自己管理<br> 增长方向为向下增长(向减小的方向增长), 与堆区相反。</p><h4 id="内存映射区:"><a href="#内存映射区:" class="headerlink" title="内存映射区:"></a>内存映射区:</h4><p> 这里保存动态链接库, 地址在栈区和堆区之间。</p><h4 id="堆区:"><a href="#堆区:" class="headerlink" title="堆区:"></a>堆区:</h4><p> 这里保存用户自己申请的内存, 这部分内存需要用户自己释放, 例如new申请的内存要用delete释放, 同理malloc 与 free。</p><h4 id="bss-未初始化全局变量区"><a href="#bss-未初始化全局变量区" class="headerlink" title=".bss 未初始化全局变量区"></a>.bss 未初始化全局变量区</h4><blockquote><p>此处保存全局变量和静态变量</p></blockquote><h4 id="data-已初始化全局变量区"><a href="#data-已初始化全局变量区" class="headerlink" title=".data 已初始化全局变量区"></a>.data 已初始化全局变量区</h4><blockquote><p>同上, 只是这里保存的是已初始化的</p></blockquote><h4 id="text"><a href="#text" class="headerlink" title=".text"></a>.text</h4><blockquote><p>程序代码, 即CPU可执行的二进制代码, 不是C或C++等代码</p><p>常量: 如const 和 1 、 ”helloword“等</p></blockquote>]]></content>
<categories>
<category> Linux基础 </category>
</categories>
<tags>
<tag> Linux </tag>
</tags>
</entry>
<entry>
<title>通过运行窗口启动自己安装的应用</title>
<link href="7133041a/"/>
<url>7133041a/</url>
<content type="html"><![CDATA[<p>前段时间安装的半透明bash感觉挺好看的, 再配上音乐的桌面写真, 但是烦恼的是桌面太多快捷方式之类的, 全部隐藏吧, 感觉打开很麻烦, 放到开始的磁力贴那里也不方便. 但是想起来 win+r 这是个好东西啊, 为什么不利用下呢, 于是开始了捣鼓之旅~</p><a id="more"></a><p>首先我们要找到它能启动哪个文件夹下的快捷方式. 输入命令%windir% 就会打开C:\WINDOWS 这个目录, 也可以手动打开这个目录.</p><p><img src="/7133041a/20180209124059682.png" alt="img">)<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><p>然后把你桌面上的快捷方式或者链接文件放到这个目录下就可以了. </p><p>然后呢我们把快捷方式改个名, 不然QQ的时候我们还要输入腾讯QQ多麻烦, 我们把快捷方式重命名为QQ就可以了, 然后启动的时候是不区分大小写的, 因此输入qq也可以</p><p><img src="/7133041a/20180209124337522.png" alt="img">)<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><p>然后win+r 输入 qq就可以启动了呢, 其他的应用也是可以的</p><p><img src="/7133041a/20180209124413269.png" alt="img">)<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p>]]></content>
<categories>
<category> tool </category>
</categories>
<tags>
<tag> windows </tag>
</tags>
</entry>
<entry>
<title>把wsl的vim内容复制到windows粘贴板上</title>
<link href="b32afe9e/"/>
<url>b32afe9e/</url>
<content type="html"><![CDATA[<p>一直比较喜欢用vim, 为此还装了双系统, 在Ubuntu上写代码,但是好不方便, 现在出了个ubuntu on windows 10, 耐不住寂寞就安装了个, 顺手就配置了vim, 但是写算法的我需要复制代码交到oj上啊, 尴尬的一幕出现了, 这是两个系统, 用的不是一个剪切板啊。然后就开始了我折腾的旅程(废话好多。。。逃~)</p><p>找了找windows, 在C:\Windows\System32 下有个 clip.exe 文件, 这就是我们用的剪切功能,如果在bash里运行呢, 会不会就是写入win10的剪切板, 试了下果然!太棒了。</p><a id="more"></a><p>然后就可以在.vimrc下写映射了。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">map <F3> : call CopyToWindows()<CR></span><br><span class="line">map! <F3> <ESC> : call CopyToWindows()<CR></span><br><span class="line">func! CopyToWindows()</span><br><span class="line"> exec "w"</span><br><span class="line"> exec "!cat % |/mnt/c/Windows/System32/clip.exe"</span><br><span class="line">endfunc</span><br></pre></td></tr></table></figure><p><img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><p>这样按F3就可以把当前vim打开的文件内容复制到win10的粘贴板了, 没啥技术含量, 就是cat下当前文件 把文件内容输送给clip.exe命令</p>]]></content>
<categories>
<category> skill </category>
</categories>
<tags>
<tag> windows </tag>
</tags>
</entry>
<entry>
<title>设置WSL可远程连接</title>
<link href="c67633e4/"/>
<url>c67633e4/</url>
<content type="html"><![CDATA[<p>为了可以在学校机房的电脑上使用我熟悉的环境也是蛮拼的, 特地把WSL设置成了远程连接. 到时候就可以通过xshell连接了, 使用我心爱的vim了, 并且还不用配置, 哈哈哈哈~</p><a id="more"></a><p>首先更新一下自带的sshserver 卸载了更新下源再安装即可, 安装选择当前源当中的主要版本</p><p>然后就是配置ssh的配置文件:</p><p>打开配置文件: </p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo vim /etc/ssh/sshd_config</span><br></pre></td></tr></table></figure><p><img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><p>写入:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Port 2222 #设置ssh的端口号, 由于22在windows中有别的用处, 尽量不修改系统的端口号</span><br><span class="line">PermitRootLogin yes # 可以root远程登录</span><br><span class="line">PasswordAuthentication yes # 密码验证登录</span><br><span class="line">AllowUsers sky # 远程登录时的用户名</span><br></pre></td></tr></table></figure><p><img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><p>重启服务:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo service ssh --full-restart</span><br></pre></td></tr></table></figure><p><img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><p>这个时候你自己电脑上的xhell是可以连接的了, 但是想要在其他的计算机上访问, 就需要系统开放端口了.</p><p>这是后需要到防火墙设置开放2222端口</p><p>防火墙->高级设置->入站规则->新建规则</p><p><img src="/c67633e4/20180928162108931.png" alt="img">)<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><p>端口->下一步</p><p>选择tcp 特定本地端口 2222</p><p><img src="/c67633e4/20180928162242346.png" alt="img">)<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><p>允许连接, 默认都选上, 下一步填个名字 完成</p><p>这个时候就可以通过网络进行ssh远程登录了</p>]]></content>
<categories>
<category> setting </category>
</categories>
<tags>
<tag> wsl </tag>
</tags>
</entry>
<entry>
<title>安装STL的man文档</title>
<link href="b148353a/"/>
<url>b148353a/</url>
<content type="html"><![CDATA[<p>摘要:<br> 现man一样显示stl的帮助文档</p><a id="more"></a><p>既然你都已经搜到这个问题了, 那你一定知道man还是很好用的, 而且比较权威, 毕竟官方带的… 废话不多说, 一开始官方给的文档是不全的, 有些函数里面没有, 例如STL等</p><p>检查一下自己是否安装了:</p><p><img src="/b148353a/20180923165031823.png" alt="img">)<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><p>接下来就安装stl的帮助文档</p><p>首先从<a href="http://www.mirrorservice.org/sites/sourceware.org/pub/gcc/libstdc%2B%2B/doxygen/" target="_blank" rel="noopener">http://www.mirrorservice.org/sites/sourceware.org/pub/gcc/libstdc%2b%2b/doxygen/</a> 下载帮助文档 我下载的是 libstdc++-man.4.4.0 .tar.bz2</p><p>然后将解压出的文件夹下man3中的内容都拷贝到 /usr/share/man/man3/</p><p>然后再试一下 </p><p><img src="/b148353a/2018092317292672.png" alt="img">)<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><p>大功告成!!! 不要忘了加std::哦~</p>]]></content>
<categories>
<category> tool </category>
</categories>
<tags>
<tag> tool </tag>
<tag> wsl </tag>
</tags>
</entry>
<entry>
<title>bash on win10 半透明效果及缓冲区大小设置</title>
<link href="96f50417/"/>
<url>96f50417/</url>
<content type="html"><![CDATA[<p>一、bash半透明效果设置</p><p>先来两张效果图</p><p><img src="/96f50417/20180209124830981.png" alt="img"> </p><p><img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><p><img src="/96f50417/20180209124947571.png" alt="img">)<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><a id="more"></a><p>这样写代码是不是少了点枯燥多了点享受呢<del>.</del></p><p>怎么弄得呢?</p><p>首先设置窗口的半透明:(右键窗口上边框就可以, 里面有个默认值这个是永久设置, 还有个属性, 这个是只是本次设置有效,重新打开窗口就没了)</p><p><img src="/96f50417/20180209125115397.png" alt="img">)<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p><p>然后其他字体, 以及窗口的大小自己根据显示的大小设置即可.</p><p>还有个问题就是如果使用了桌面写真, 不能使用窗口最大化, 如果最大化, 音乐的歌词就停了. 所以设置的窗口大一点, 打开就跟全屏差不多, 但是这是窗口化.</p><h3 id="二、缓冲区大小设置"><a href="#二、缓冲区大小设置" class="headerlink" title="二、缓冲区大小设置"></a>二、缓冲区大小设置</h3><p>当使用bash的时候设置缓冲区大小不仅仅是bash.rc 文件了, 还与windows窗口设置有关, 如果你有很多, 窗口不然看白搭.</p><p>设置窗口能显示的条数:</p><p>跟之前设置一样, 打开窗口默认值设置, 选择布局, 然后屏幕缓冲区大小的高度就是能显示的行数.</p><p><img src="/96f50417/20180209125526649.png" alt="img">)<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" alt="点击并拖拽以移动"></p>]]></content>
<categories>
<category> tool </category>
</categories>
<tags>
<tag> wsl </tag>
</tags>
</entry>
</search>