<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>C/C++ on 醉后的星星</title><link>https://kizx.github.io/tags/c/c++/</link><description>Recent content in C/C++ on 醉后的星星</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><copyright>kizx</copyright><lastBuildDate>Sun, 13 Jul 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://kizx.github.io/tags/c/c++/index.xml" rel="self" type="application/rss+xml"/><item><title>Win32_API修改EXE文件ICON图标</title><link>https://kizx.github.io/post/win32_api%E4%BF%AE%E6%94%B9exe%E6%96%87%E4%BB%B6icon%E5%9B%BE%E6%A0%87/</link><pubDate>Sun, 13 Jul 2025 00:00:00 +0000</pubDate><guid>https://kizx.github.io/post/win32_api%E4%BF%AE%E6%94%B9exe%E6%96%87%E4%BB%B6icon%E5%9B%BE%E6%A0%87/</guid><description>&lt;h2 id="说明">&lt;a href="#%e8%af%b4%e6%98%8e" class="header-anchor">&lt;/a>说明
&lt;/h2>&lt;p>EXE文件的ICON图标一般由数个图标组成，在更新ICON图标时需要逐一添加每个图标，再添加ICON_GROUP目录，可以使用&lt;code>ResourceHacker&lt;/code>软件进行查看。&lt;/p>
&lt;p>EXE文件中的图标数据结构和ICON图标文件结构很相似，唯一区别在于ICON图标的&lt;code>ICONDIRENTRY&lt;/code>最后一个字段标注的是图像数据首地址，EXE文件的&lt;code>GRPICONDIRENTRY&lt;/code>最后一个字段标注的是图标的ID。&lt;/p>
&lt;h2 id="代码">&lt;a href="#%e4%bb%a3%e7%a0%81" class="header-anchor">&lt;/a>代码
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;windows.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;stdio.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#pragma pack(push, 2) &lt;/span>&lt;span style="color:#75715e">//结构体需要双字节对齐
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">typedef&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> WORD idReserved; &lt;span style="color:#75715e">// Reserved (must be 0)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> WORD idType; &lt;span style="color:#75715e">// Resource Type (1 for icons)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> WORD idCount; &lt;span style="color:#75715e">// How many images?
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">// ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of &amp;#39;em)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>} ICONDIR;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">typedef&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> BYTE bWidth; &lt;span style="color:#75715e">// Width, in pixels, of the image
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> BYTE bHeight; &lt;span style="color:#75715e">// Height, in pixels, of the image
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> BYTE bColorCount; &lt;span style="color:#75715e">// Number of colors in image (0 if &amp;gt;=8bpp)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> BYTE bReserved; &lt;span style="color:#75715e">// Reserved ( must be 0)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> WORD wPlanes; &lt;span style="color:#75715e">// Color Planes
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> WORD wBitCount; &lt;span style="color:#75715e">// Bits per pixel
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> DWORD dwBytesInRes; &lt;span style="color:#75715e">// How many bytes in this resource?
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> DWORD dwImageOffset; &lt;span style="color:#75715e">// Where in the file is this image?
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>} ICONDIRENTRY;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">typedef&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> BITMAPINFOHEADER icHeader; &lt;span style="color:#75715e">// DIB header
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> RGBQUAD icColors[&lt;span style="color:#ae81ff">1&lt;/span>]; &lt;span style="color:#75715e">// Color table
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> BYTE icXOR[&lt;span style="color:#ae81ff">1&lt;/span>]; &lt;span style="color:#75715e">// DIB bits for XOR mask
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> BYTE icAND[&lt;span style="color:#ae81ff">1&lt;/span>]; &lt;span style="color:#75715e">// DIB bits for AND mask
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>} ICONIMAGE;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">typedef&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> WORD idReserved; &lt;span style="color:#75715e">// Reserved (must be 0)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> WORD idType; &lt;span style="color:#75715e">// Resource type (1 for icons)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> WORD idCount; &lt;span style="color:#75715e">// How many images?
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">// GRPICONDIRENTRY idEntries[1]; // The entries for each image
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>} GRPICONDIR;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">typedef&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> BYTE bWidth; &lt;span style="color:#75715e">// Width, in pixels, of the image
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> BYTE bHeight; &lt;span style="color:#75715e">// Height, in pixels, of the image
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> BYTE bColorCount; &lt;span style="color:#75715e">// Number of colors in image (0 if &amp;gt;=8bpp)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> BYTE bReserved; &lt;span style="color:#75715e">// Reserved
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> WORD wPlanes; &lt;span style="color:#75715e">// Color Planes
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> WORD wBitCount; &lt;span style="color:#75715e">// Bits per pixel
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> DWORD dwBytesInRes; &lt;span style="color:#75715e">// how many bytes in this resource?
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> WORD nID; &lt;span style="color:#75715e">// the ID
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>} GRPICONDIRENTRY;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#pragma pack(pop)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>(&lt;span style="color:#66d9ef">int&lt;/span> argc, &lt;span style="color:#66d9ef">char&lt;/span> &lt;span style="color:#f92672">*&lt;/span>argv[]) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// if (argc != 3) {
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">// printf(&amp;#34;Usage: %s &amp;lt;target_exe&amp;gt; &amp;lt;new_icon.ico&amp;gt;\n&amp;#34;, argv[0]);
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">// return 1;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">// }
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">//
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">// const char *exePath = argv[1];
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">// const char *iconPath = argv[2];
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">char&lt;/span> exePath[] &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;pip.exe&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">char&lt;/span> iconPath[] &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;app.ico&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 打开图标文件
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> HANDLE hIcon &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">CreateFile&lt;/span>(iconPath, GENERIC_READ, &lt;span style="color:#ae81ff">0&lt;/span>, NULL,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (hIcon &lt;span style="color:#f92672">==&lt;/span> INVALID_HANDLE_VALUE) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;[%lu]Error opening icon file&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">GetLastError&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 获取图标文件大小
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> DWORD iconSize &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">GetFileSize&lt;/span>(hIcon, NULL);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (iconSize &lt;span style="color:#f92672">==&lt;/span> INVALID_FILE_SIZE) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;[%lu]Error getting icon file size&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">GetLastError&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">CloseHandle&lt;/span>(hIcon);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 读取图标文件
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> BYTE&lt;span style="color:#f92672">*&lt;/span> iconData &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">malloc&lt;/span>(iconSize);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> DWORD bytesRead;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#f92672">!&lt;/span>&lt;span style="color:#a6e22e">ReadFile&lt;/span>(hIcon, iconData, iconSize, &lt;span style="color:#f92672">&amp;amp;&lt;/span>bytesRead, NULL) &lt;span style="color:#f92672">||&lt;/span> bytesRead &lt;span style="color:#f92672">!=&lt;/span> iconSize) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;[%lu]Error reading icon file&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">GetLastError&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">free&lt;/span>(iconData);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">CloseHandle&lt;/span>(hIcon);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">CloseHandle&lt;/span>(hIcon);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 解析图标文件目录
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> ICONDIR&lt;span style="color:#f92672">*&lt;/span> iconDir &lt;span style="color:#f92672">=&lt;/span> (ICONDIR&lt;span style="color:#f92672">*&lt;/span>)iconData;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (iconDir&lt;span style="color:#f92672">-&amp;gt;&lt;/span>idReserved &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span> &lt;span style="color:#f92672">||&lt;/span> iconDir&lt;span style="color:#f92672">-&amp;gt;&lt;/span>idType &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Invalid icon file format&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">free&lt;/span>(iconData);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 计算图标组资源大小
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> DWORD groupSize &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">sizeof&lt;/span>(GRPICONDIR) &lt;span style="color:#f92672">+&lt;/span> iconDir&lt;span style="color:#f92672">-&amp;gt;&lt;/span>idCount &lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#66d9ef">sizeof&lt;/span>(GRPICONDIRENTRY);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> BYTE&lt;span style="color:#f92672">*&lt;/span> groupData &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">malloc&lt;/span>(groupSize);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GRPICONDIR&lt;span style="color:#f92672">*&lt;/span> grpIconDir &lt;span style="color:#f92672">=&lt;/span> (GRPICONDIR&lt;span style="color:#f92672">*&lt;/span>)groupData;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> grpIconDir&lt;span style="color:#f92672">-&amp;gt;&lt;/span>idReserved &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> grpIconDir&lt;span style="color:#f92672">-&amp;gt;&lt;/span>idType &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>; &lt;span style="color:#75715e">// RT_ICON
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> grpIconDir&lt;span style="color:#f92672">-&amp;gt;&lt;/span>idCount &lt;span style="color:#f92672">=&lt;/span> iconDir&lt;span style="color:#f92672">-&amp;gt;&lt;/span>idCount;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 创建图标组资源
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> ICONDIRENTRY&lt;span style="color:#f92672">*&lt;/span> iconEntries &lt;span style="color:#f92672">=&lt;/span> (ICONDIRENTRY&lt;span style="color:#f92672">*&lt;/span>)(iconData &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#66d9ef">sizeof&lt;/span>(ICONDIR));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GRPICONDIRENTRY&lt;span style="color:#f92672">*&lt;/span> grpEntries &lt;span style="color:#f92672">=&lt;/span> (GRPICONDIRENTRY&lt;span style="color:#f92672">*&lt;/span>)(groupData &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#66d9ef">sizeof&lt;/span>(GRPICONDIR));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> (&lt;span style="color:#66d9ef">int&lt;/span> i &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>; i &lt;span style="color:#f92672">&amp;lt;&lt;/span> iconDir&lt;span style="color:#f92672">-&amp;gt;&lt;/span>idCount; i&lt;span style="color:#f92672">++&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> grpEntries[i].bWidth &lt;span style="color:#f92672">=&lt;/span> iconEntries[i].bWidth;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> grpEntries[i].bHeight &lt;span style="color:#f92672">=&lt;/span> iconEntries[i].bHeight;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> grpEntries[i].bColorCount &lt;span style="color:#f92672">=&lt;/span> iconEntries[i].bColorCount;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> grpEntries[i].bReserved &lt;span style="color:#f92672">=&lt;/span> iconEntries[i].bReserved;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> grpEntries[i].wPlanes &lt;span style="color:#f92672">=&lt;/span> iconEntries[i].wPlanes;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> grpEntries[i].wBitCount &lt;span style="color:#f92672">=&lt;/span> iconEntries[i].wBitCount;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> grpEntries[i].dwBytesInRes &lt;span style="color:#f92672">=&lt;/span> iconEntries[i].dwBytesInRes;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> grpEntries[i].nID &lt;span style="color:#f92672">=&lt;/span> i &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>; &lt;span style="color:#75715e">// 资源ID从1开始
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 开始更新EXE资源
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> HANDLE hUpdate &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">BeginUpdateResource&lt;/span>(exePath, FALSE);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (hUpdate &lt;span style="color:#f92672">==&lt;/span> NULL) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;BeginUpdateResource failed: %lu&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">GetLastError&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">free&lt;/span>(iconData);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">free&lt;/span>(groupData);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 删除现有的图标组资源
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#f92672">!&lt;/span>&lt;span style="color:#a6e22e">UpdateResource&lt;/span>(hUpdate, RT_GROUP_ICON, &lt;span style="color:#a6e22e">MAKEINTRESOURCE&lt;/span>(&lt;span style="color:#ae81ff">101&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">MAKELANGID&lt;/span>(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, &lt;span style="color:#ae81ff">0&lt;/span>)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;[%lu]Warning: Failed to remove old icon group ID-101&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">GetLastError&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 删除现有的图标资源
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">for&lt;/span> (&lt;span style="color:#66d9ef">int&lt;/span> i &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>; i &lt;span style="color:#f92672">&amp;lt;=&lt;/span> &lt;span style="color:#ae81ff">7&lt;/span>; i&lt;span style="color:#f92672">++&lt;/span>) { &lt;span style="color:#75715e">// 删除ID 1-7的图标资源
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#f92672">!&lt;/span>&lt;span style="color:#a6e22e">UpdateResource&lt;/span>(hUpdate, RT_ICON, &lt;span style="color:#a6e22e">MAKEINTRESOURCE&lt;/span>(i),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">MAKELANGID&lt;/span>(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, &lt;span style="color:#ae81ff">0&lt;/span>)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;[%lu]Warning: Failed to remove old icon ID-%d&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">GetLastError&lt;/span>(), i);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> };
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 添加新的图标组资源
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#f92672">!&lt;/span>&lt;span style="color:#a6e22e">UpdateResource&lt;/span>(hUpdate, RT_GROUP_ICON, &lt;span style="color:#a6e22e">MAKEINTRESOURCE&lt;/span>(&lt;span style="color:#ae81ff">101&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">MAKELANGID&lt;/span>(LANG_NEUTRAL, SUBLANG_NEUTRAL),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> groupData, groupSize)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;[%lu]UpdateResource (group icon) failed&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">GetLastError&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">free&lt;/span>(iconData);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">free&lt;/span>(groupData);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">EndUpdateResource&lt;/span>(hUpdate, TRUE);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 添加各个图标资源
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">for&lt;/span> (&lt;span style="color:#66d9ef">int&lt;/span> i &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>; i &lt;span style="color:#f92672">&amp;lt;&lt;/span> iconDir&lt;span style="color:#f92672">-&amp;gt;&lt;/span>idCount; i&lt;span style="color:#f92672">++&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> DWORD offset &lt;span style="color:#f92672">=&lt;/span> iconEntries[i].dwImageOffset;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> DWORD size &lt;span style="color:#f92672">=&lt;/span> iconEntries[i].dwBytesInRes;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (offset &lt;span style="color:#f92672">+&lt;/span> size &lt;span style="color:#f92672">&amp;gt;&lt;/span> iconSize) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Icon data out of bounds: entry %d&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, i);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">continue&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#f92672">!&lt;/span>&lt;span style="color:#a6e22e">UpdateResource&lt;/span>(hUpdate, RT_ICON, &lt;span style="color:#a6e22e">MAKEINTRESOURCE&lt;/span>(i &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">MAKELANGID&lt;/span>(LANG_NEUTRAL, SUBLANG_NEUTRAL),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> iconData &lt;span style="color:#f92672">+&lt;/span> offset, size)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;[%lu]UpdateResource (icon %d) failed&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, i, &lt;span style="color:#a6e22e">GetLastError&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 完成资源更新
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#f92672">!&lt;/span>&lt;span style="color:#a6e22e">EndUpdateResource&lt;/span>(hUpdate, FALSE)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;[%lu]EndUpdateResource failed&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">GetLastError&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">free&lt;/span>(iconData);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">free&lt;/span>(groupData);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Icon group updated successfully!&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">free&lt;/span>(iconData);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">free&lt;/span>(groupData);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>VS2019配置pthread多线程</title><link>https://kizx.github.io/post/vs2019%E9%85%8D%E7%BD%AEpthread%E5%A4%9A%E7%BA%BF%E7%A8%8B/</link><pubDate>Tue, 28 Jun 2022 15:32:00 +0000</pubDate><guid>https://kizx.github.io/post/vs2019%E9%85%8D%E7%BD%AEpthread%E5%A4%9A%E7%BA%BF%E7%A8%8B/</guid><description>&lt;p>在VS里用MS编译器不能直接调用pthread库，需要先自行下载该库：
&lt;a class="link" href="http://sourceware.org/pub/pthreads-win32/pthreads-w32-2-9-1-release.zip" target="_blank" rel="noopener"
>http://sourceware.org/pub/pthreads-win32/pthreads-w32-2-9-1-release.zip&lt;/a>
解压后用的到的只有&lt;code>Pre-built.2&lt;/code>文件夹下的文件。&lt;/p>
&lt;h2 id="配置">&lt;a href="#%e9%85%8d%e7%bd%ae" class="header-anchor">&lt;/a>配置
&lt;/h2>&lt;p>如下图分别配置三大项：&lt;/p>
&lt;ul>
&lt;li>包含目录&amp;ndash;&amp;gt;&amp;hellip;\pthreads-w32-2-9-1-release\Pre-built.2\include&lt;/li>
&lt;li>库目录&amp;ndash;&amp;gt;&amp;hellip;\pthreads-w32-2-9-1-release\Pre-built.2\lib\x86&lt;/li>
&lt;li>附加依赖项&amp;ndash;&amp;gt;pthreadVC2.lib&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://www.2bboy.com/usr/uploads/2022/06/1673997423.png"
loading="lazy"
>
&lt;img src="https://www.2bboy.com/usr/uploads/2022/06/743816291.png"
loading="lazy"
>&lt;/p>
&lt;ul>
&lt;li>如果代码运行报错：“timespec”;”struct”类型重定义。
解决方法：在pthread.h在第35行加入如下代码：&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-C" data-lang="C">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#define HAVE_STRUCT_TIMESPEC
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>或者在项目属性-&amp;gt;C\C++-&amp;gt;预处理器-&amp;gt;预处理器定义添加&lt;code>HAVE_STRUCT_TIMESPEC&lt;/code>。&lt;/p>
&lt;ul>
&lt;li>如果代码运行报错：找不到pthreadVC2.dll。
解决方法：将pthreadVC2.dll拷贝到项目的Debug目录下&lt;/li>
&lt;/ul>
&lt;h2 id="示例代码">&lt;a href="#%e7%a4%ba%e4%be%8b%e4%bb%a3%e7%a0%81" class="header-anchor">&lt;/a>示例代码
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;stdio.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;stdlib.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;Windows.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;pthread.h&amp;gt; //使用多线程时需要添加&amp;lt;pthread.h&amp;gt;这个头文件&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> s &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">void&lt;/span>&lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#a6e22e">transmit&lt;/span>(&lt;span style="color:#66d9ef">void&lt;/span>&lt;span style="color:#f92672">*&lt;/span> args) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">char&lt;/span>&lt;span style="color:#f92672">*&lt;/span> name &lt;span style="color:#f92672">=&lt;/span> (&lt;span style="color:#66d9ef">char&lt;/span>&lt;span style="color:#f92672">*&lt;/span>)args;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> (&lt;span style="color:#66d9ef">int&lt;/span> i &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>; i &lt;span style="color:#f92672">&amp;lt;&lt;/span> &lt;span style="color:#ae81ff">1000&lt;/span>; i&lt;span style="color:#f92672">++&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> s&lt;span style="color:#f92672">++&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;----------%s : s = %d----------&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, name, s);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Sleep&lt;/span>(&lt;span style="color:#ae81ff">1000&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">void&lt;/span>&lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#a6e22e">receive&lt;/span>(&lt;span style="color:#66d9ef">void&lt;/span>&lt;span style="color:#f92672">*&lt;/span> args) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">char&lt;/span>&lt;span style="color:#f92672">*&lt;/span> name &lt;span style="color:#f92672">=&lt;/span> (&lt;span style="color:#66d9ef">char&lt;/span>&lt;span style="color:#f92672">*&lt;/span>)args;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">while&lt;/span> (&lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%s : s = %d&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, name, s);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Sleep&lt;/span>(&lt;span style="color:#ae81ff">100&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">pthread_t&lt;/span> tx, rx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">pthread_create&lt;/span>(&lt;span style="color:#f92672">&amp;amp;&lt;/span>tx, NULL, transmit, &lt;span style="color:#e6db74">&amp;#34;TX&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">pthread_create&lt;/span>(&lt;span style="color:#f92672">&amp;amp;&lt;/span>rx, NULL, receive, &lt;span style="color:#e6db74">&amp;#34;RX&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">pthread_join&lt;/span>(tx, NULL);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">pthread_join&lt;/span>(rx, NULL);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="参考">&lt;a href="#%e5%8f%82%e8%80%83" class="header-anchor">&lt;/a>参考
&lt;/h2>&lt;p>&lt;a class="link" href="https://www.cnblogs.com/maycpou/p/13895295.html" target="_blank" rel="noopener"
>https://www.cnblogs.com/maycpou/p/13895295.html&lt;/a>
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/97418361" target="_blank" rel="noopener"
>https://zhuanlan.zhihu.com/p/97418361&lt;/a>&lt;/p></description></item><item><title>CLion编译运行OpenGL项目</title><link>https://kizx.github.io/post/clion%E7%BC%96%E8%AF%91%E8%BF%90%E8%A1%8Copengl%E9%A1%B9%E7%9B%AE/</link><pubDate>Thu, 04 Jun 2020 13:31:51 +0000</pubDate><guid>https://kizx.github.io/post/clion%E7%BC%96%E8%AF%91%E8%BF%90%E8%A1%8Copengl%E9%A1%B9%E7%9B%AE/</guid><description>&lt;p>前面已经用Visual Studio成功运行了OpenGL了，但是VS的界面比较丑，而且代码提示和补全等各方面不够人性化（主要是我不习惯），相比之下，JB家的CLion虽然运行上慢一点，bug多一点，配置麻烦一点（喂！这缺点太多了吧），但是为了颜值和流畅的编程体验，用一下也不是不可以。&lt;/p>
&lt;h2 id="配置">&lt;a href="#%e9%85%8d%e7%bd%ae" class="header-anchor">&lt;/a>配置
&lt;/h2>&lt;p>安装什么的就不说了，新建一个项目，Clion会自动生成一个&lt;code>CMakeLists.txt&lt;/code>和&lt;code>main.cpp&lt;/code>，点击运行没毛病，那就进入opengl的环境配置。
我这里用的是glut库，别的库参照着配置问题应该不大。在vs里我们是通过右键项目属性设置“三大件”的，但CLion是通过cmake来管理编译和链接的，只能通过手写CMakelists来进行配置。其实配置思路都差不多，手写配置还可以更清晰。
以下是&lt;code>CMakeLists.txt&lt;/code>内容：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cmake" data-lang="cmake">&lt;span style="display:flex;">&lt;span>cmake_minimum_required(&lt;span style="color:#e6db74">VERSION&lt;/span> &lt;span style="color:#e6db74">3.16&lt;/span>)&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>project(&lt;span style="color:#e6db74">gl_demo&lt;/span>)&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>set(&lt;span style="color:#e6db74">CMAKE_CXX_STANDARD&lt;/span> &lt;span style="color:#e6db74">14&lt;/span>)&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>include_directories(&lt;span style="color:#e6db74">C:/dev/glut/include&lt;/span>) &lt;span style="color:#75715e"># 添加include头文件目录
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>link_directories(&lt;span style="color:#e6db74">C:/dev//glut/lib&lt;/span>) &lt;span style="color:#75715e"># 添加lib库目录
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>add_executable(&lt;span style="color:#e6db74">gl_demo&lt;/span> &lt;span style="color:#e6db74">main.cpp&lt;/span>)&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>target_link_libraries(&lt;span style="color:#e6db74">gl_demo&lt;/span> &lt;span style="color:#e6db74">glut32.lib&lt;/span> &lt;span style="color:#e6db74">opengl32.lib&lt;/span>) &lt;span style="color:#75715e"># 添加链接的具体lib项
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>以下是demo&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cpp" data-lang="cpp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Lines.c
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// OpenGL SuperBible, Chapter 4
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Demonstrates primitive GL_LINES
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Program by Richard S. Wright Jr.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;gl/glut.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;math.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Define a constant for the value of PI
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#75715e">#define GL_PI 3.1415f
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Rotation amounts
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">static&lt;/span> GLfloat xRot &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">static&lt;/span> GLfloat yRot &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Called to draw scene
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">RenderScene&lt;/span>(&lt;span style="color:#66d9ef">void&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GLfloat x, y, z, angle; &lt;span style="color:#75715e">// Storage for coordinates and angles
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Clear the window with current clearing color
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> glClear(GL_COLOR_BUFFER_BIT);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Save matrix state and do the rotation
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> glPushMatrix();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glRotatef(xRot, &lt;span style="color:#ae81ff">1.0f&lt;/span>, &lt;span style="color:#ae81ff">0.0f&lt;/span>, &lt;span style="color:#ae81ff">0.0f&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glRotatef(yRot, &lt;span style="color:#ae81ff">0.0f&lt;/span>, &lt;span style="color:#ae81ff">1.0f&lt;/span>, &lt;span style="color:#ae81ff">0.0f&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Call only once for all remaining points
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> glBegin(GL_LINES);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> z &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> (angle &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0.0f&lt;/span>; angle &lt;span style="color:#f92672">&amp;lt;=&lt;/span> GL_PI &lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#ae81ff">3.0f&lt;/span>; angle &lt;span style="color:#f92672">+=&lt;/span> &lt;span style="color:#ae81ff">0.5f&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Top half of the circle
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> x &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">50.0f&lt;/span> &lt;span style="color:#f92672">*&lt;/span> cos(angle);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> y &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">50.0f&lt;/span> &lt;span style="color:#f92672">*&lt;/span> sin(angle);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glVertex3f(x, y, z);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Bottom half of the circle
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> x &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">50.0f&lt;/span> &lt;span style="color:#f92672">*&lt;/span> cos(angle &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#ae81ff">3.1415f&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> y &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">50.0f&lt;/span> &lt;span style="color:#f92672">*&lt;/span> sin(angle &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#ae81ff">3.1415f&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glVertex3f(x, y, z);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Done drawing points
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> glEnd();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Restore transformations
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> glPopMatrix();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Flush drawing commands
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> glutSwapBuffers();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// This function does any needed initialization on the rendering
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">SetupRC&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Black background
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> glClearColor(&lt;span style="color:#ae81ff">0.0f&lt;/span>, &lt;span style="color:#ae81ff">0.0f&lt;/span>, &lt;span style="color:#ae81ff">0.0f&lt;/span>, &lt;span style="color:#ae81ff">1.0f&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Set drawing color to green
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> glColor3f(&lt;span style="color:#ae81ff">0.0f&lt;/span>, &lt;span style="color:#ae81ff">1.0f&lt;/span>, &lt;span style="color:#ae81ff">0.0f&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">SpecialKeys&lt;/span>(&lt;span style="color:#66d9ef">int&lt;/span> key, &lt;span style="color:#66d9ef">int&lt;/span> x, &lt;span style="color:#66d9ef">int&lt;/span> y) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">==&lt;/span> GLUT_KEY_UP)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xRot &lt;span style="color:#f92672">-=&lt;/span> &lt;span style="color:#ae81ff">5.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">==&lt;/span> GLUT_KEY_DOWN)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xRot &lt;span style="color:#f92672">+=&lt;/span> &lt;span style="color:#ae81ff">5.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">==&lt;/span> GLUT_KEY_LEFT)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> yRot &lt;span style="color:#f92672">-=&lt;/span> &lt;span style="color:#ae81ff">5.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">==&lt;/span> GLUT_KEY_RIGHT)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> yRot &lt;span style="color:#f92672">+=&lt;/span> &lt;span style="color:#ae81ff">5.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">&amp;gt;&lt;/span> &lt;span style="color:#ae81ff">356.0f&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xRot &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">&amp;lt;&lt;/span> &lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1.0f&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xRot &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">355.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">&amp;gt;&lt;/span> &lt;span style="color:#ae81ff">356.0f&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> yRot &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">&amp;lt;&lt;/span> &lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1.0f&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> yRot &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">355.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Refresh the Window
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> glutPostRedisplay();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">KeyPressFunc&lt;/span>(&lt;span style="color:#66d9ef">unsigned&lt;/span> &lt;span style="color:#66d9ef">char&lt;/span> key, &lt;span style="color:#66d9ef">int&lt;/span> x, &lt;span style="color:#66d9ef">int&lt;/span> y) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">32&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xRot &lt;span style="color:#f92672">-=&lt;/span> &lt;span style="color:#ae81ff">5.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">97&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xRot &lt;span style="color:#f92672">+=&lt;/span> &lt;span style="color:#ae81ff">5.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">98&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> yRot &lt;span style="color:#f92672">-=&lt;/span> &lt;span style="color:#ae81ff">5.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">99&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> yRot &lt;span style="color:#f92672">+=&lt;/span> &lt;span style="color:#ae81ff">5.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">&amp;gt;&lt;/span> &lt;span style="color:#ae81ff">356.0f&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xRot &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">&amp;lt;&lt;/span> &lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1.0f&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xRot &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">355.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">&amp;gt;&lt;/span> &lt;span style="color:#ae81ff">356.0f&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> yRot &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (key &lt;span style="color:#f92672">&amp;lt;&lt;/span> &lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1.0f&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> yRot &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">355.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Refresh the Window
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> glutPostRedisplay();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">ChangeSize&lt;/span>(&lt;span style="color:#66d9ef">int&lt;/span> w, &lt;span style="color:#66d9ef">int&lt;/span> h) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GLfloat nRange &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">100.0f&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Prevent a divide by zero
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> (h &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> h &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Set Viewport to window dimensions
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> glViewport(&lt;span style="color:#ae81ff">0&lt;/span>, &lt;span style="color:#ae81ff">0&lt;/span>, w, h);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Reset coordinate system
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> glMatrixMode(GL_PROJECTION);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glLoadIdentity();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Establish clipping volume (left, right, bottom, top, near, far)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> (w &lt;span style="color:#f92672">&amp;lt;=&lt;/span> h)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glOrtho(&lt;span style="color:#f92672">-&lt;/span>nRange, nRange, &lt;span style="color:#f92672">-&lt;/span>nRange &lt;span style="color:#f92672">*&lt;/span> h &lt;span style="color:#f92672">/&lt;/span> w, nRange &lt;span style="color:#f92672">*&lt;/span> h &lt;span style="color:#f92672">/&lt;/span> w, &lt;span style="color:#f92672">-&lt;/span>nRange, nRange);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">else&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glOrtho(&lt;span style="color:#f92672">-&lt;/span>nRange &lt;span style="color:#f92672">*&lt;/span> w &lt;span style="color:#f92672">/&lt;/span> h, nRange &lt;span style="color:#f92672">*&lt;/span> w &lt;span style="color:#f92672">/&lt;/span> h, &lt;span style="color:#f92672">-&lt;/span>nRange, nRange, &lt;span style="color:#f92672">-&lt;/span>nRange, nRange);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glMatrixMode(GL_MODELVIEW);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glLoadIdentity();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>(&lt;span style="color:#66d9ef">int&lt;/span> argc, &lt;span style="color:#66d9ef">char&lt;/span> &lt;span style="color:#f92672">*&lt;/span>argv[]) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GLsizei h &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">500&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GLsizei w &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">500&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GLsizei x &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">200&lt;/span>, y &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">100&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutInit(&lt;span style="color:#f92672">&amp;amp;&lt;/span>argc, argv);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutInitDisplayMode(GLUT_DOUBLE &lt;span style="color:#f92672">|&lt;/span> GLUT_RGB &lt;span style="color:#f92672">|&lt;/span> GLUT_DEPTH);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutInitWindowSize(h, w);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutInitWindowPosition(x, y);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutCreateWindow(&lt;span style="color:#e6db74">&amp;#34;Lines Example&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutDisplayFunc(RenderScene);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutReshapeFunc(ChangeSize);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutSpecialFunc(SpecialKeys);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutKeyboardFunc(KeyPressFunc);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> SetupRC();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutMainLoop();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Visual Studio配置glut/freeglut开发环境</title><link>https://kizx.github.io/post/visual-studio%E9%85%8D%E7%BD%AEglutfreeglut%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/</link><pubDate>Mon, 01 Jun 2020 08:17:00 +0000</pubDate><guid>https://kizx.github.io/post/visual-studio%E9%85%8D%E7%BD%AEglutfreeglut%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/</guid><description>&lt;p>glut/freeglut是opengl的一个封装库，虽然现在一般都是用glfw了，但一些教材和课堂上仍旧采用glut库，没办法，那就来配置一下吧。其中glut比较古老，而且好像闭源且早已不再维护了，其官网首页也直接推荐到freeglut库。freeglut是glut的开源版，且一直有人维护。
glut官网：https://www.opengl.org/resources/libraries/glut/
freeglut官网下载：https://www.transmissionzero.co.uk/software/freeglut-devel/&lt;/p>
&lt;blockquote>
&lt;p>ps:其实网上也有不少教程，但那些教程都是直接把下载好的库复制到系统文件夹和VS文件夹下，这种做法实在不优雅，更正常的做法应该是在VS的工程里进行属性配置才对。&lt;/p>&lt;/blockquote>
&lt;h2 id="freeglut配置">&lt;a href="#freeglut%e9%85%8d%e7%bd%ae" class="header-anchor">&lt;/a>freeglut配置
&lt;/h2>&lt;p>从上面的官网点击&lt;code>Download freeglut 3.0.0 for MSVC&lt;/code>下载二进制库下载解压到一个你喜欢的目录。
然后配置三大件：
添加include头文件
&lt;img src="https://pan.2bboy.com/img/2020/06/0601154913.png"
loading="lazy"
>
添加lib目录
&lt;img src="https://pan.2bboy.com/img/2020/06/0601155127.png"
loading="lazy"
>
添加lib项，其中&lt;code>opengl32.lib&lt;/code>不添加好像也行，我是配置glfw时看要加上，所以这里顺手也加上了。
&lt;img src="https://pan.2bboy.com/img/2020/06/0601155521.png"
loading="lazy"
>
ps：如果是vs2019，include和lib位置放到这里也可以
&lt;img src="https://www.2bboy.com/usr/uploads/2021/08/3686625392.png"
loading="lazy"
>
如果此时运行会报无法找到dll的错误，将&lt;code>C:\dev\freeglut\bin&lt;/code>的目录添加到系统Path变量下就行了(添加后工程得重启才能生效)
测试代码：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cpp" data-lang="cpp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;GL/glut.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">Show&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glClear(GL_COLOR_BUFFER_BIT);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glRectf(&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">0.5f&lt;/span>, &lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">0.5f&lt;/span>, &lt;span style="color:#ae81ff">0.5f&lt;/span>, &lt;span style="color:#ae81ff">0.5f&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glFlush();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>(&lt;span style="color:#66d9ef">int&lt;/span> argc, &lt;span style="color:#66d9ef">char&lt;/span>&lt;span style="color:#f92672">*&lt;/span> argv[])
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutInit(&lt;span style="color:#f92672">&amp;amp;&lt;/span>argc, argv);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutInitDisplayMode(GLUT_RGB &lt;span style="color:#f92672">|&lt;/span> GLUT_SINGLE);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutInitWindowPosition(&lt;span style="color:#ae81ff">100&lt;/span>, &lt;span style="color:#ae81ff">100&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutInitWindowSize(&lt;span style="color:#ae81ff">500&lt;/span>, &lt;span style="color:#ae81ff">500&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutCreateWindow(&lt;span style="color:#e6db74">&amp;#34;OpenGL-窗口&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutDisplayFunc(Show);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glutMainLoop();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>官方的Hello-GLUT测试代码：https://github.com/TransmissionZero/Hello-GLUT
建议自己复制粘贴这些代码运行&lt;/p>
&lt;h2 id="glut配置">&lt;a href="#glut%e9%85%8d%e7%bd%ae" class="header-anchor">&lt;/a>glut配置
&lt;/h2>&lt;p>如果非要用glut也不是不行，官方下载地址：https://www.opengl.org/resources/libraries/glut/glut_downloads.php#windows 选择&lt;code>Download the GLUT 3.6 headers and pre-compiled libraries: glutdlls36.zip&lt;/code>下载应该就可以。
下载解压后就5个文件和一个readme，这怎么用？网上的教程都是分别塞到系统目录和VS安装目录下的，这里我觉得可以像上面freeglut一样进行配置，手动将这5个文件安排成和freeglut相似的目录结构：新建三个&lt;code>bin&lt;/code>,&lt;code>include/GL&lt;/code>,&lt;code>lib&lt;/code>目录然后将5个文件一一放进去，将&lt;code>bin&lt;/code>的目录添加到系统&lt;code>path&lt;/code>环境变量。
然后后面在VS里的设置就和上面freeglut一样了，只需要将相应名称改一下就行了，测试代码也是一样的。&lt;/p></description></item><item><title>Visual Studio保存工程环境配置</title><link>https://kizx.github.io/post/visual-studio%E4%BF%9D%E5%AD%98%E5%B7%A5%E7%A8%8B%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/</link><pubDate>Sun, 31 May 2020 15:44:00 +0000</pubDate><guid>https://kizx.github.io/post/visual-studio%E4%BF%9D%E5%AD%98%E5%B7%A5%E7%A8%8B%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/</guid><description>&lt;p>要说到VS(C/C++)最麻烦的地方就是各种环境，各种库配置来配置去，因此将配置好的工程设置保存下来，以备下次新建工程时直接引用很有必要。&lt;/p>
&lt;h2 id="方法">&lt;a href="#%e6%96%b9%e6%b3%95" class="header-anchor">&lt;/a>方法
&lt;/h2>&lt;p>切到属性管理器窗口，右键选择添加一个新的属性表。
&lt;img src="https://pan.2bboy.com/img/2020/05/0531233207.png"
loading="lazy"
>
比如我们新建一个名为&lt;code>opengl&lt;/code>的属性表，然后打开任一个文件，右键点击&lt;code>opengl&lt;/code>选择属性。
&lt;img src="https://pan.2bboy.com/img/2020/05/0531233522.png"
loading="lazy"
>
然后就是对项目属性进行配置。
另外在配置时选择所有配置和所有平台可以避免各种模式都要配一遍的烦恼。
&lt;img src="https://pan.2bboy.com/img/2020/06/0601184836.png"
loading="lazy"
>&lt;/p>
&lt;hr>
&lt;p>当新建一个工程时只需要在同样的地方添加现有属性表即可。&lt;/p></description></item><item><title>OPENGL环境配置</title><link>https://kizx.github.io/post/opengl%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/</link><pubDate>Sun, 31 May 2020 04:57:00 +0000</pubDate><guid>https://kizx.github.io/post/opengl%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/</guid><description>&lt;p>基于glfw和glew进行开发配置。&lt;/p>
&lt;h2 id="下载安装库">&lt;a href="#%e4%b8%8b%e8%bd%bd%e5%ae%89%e8%a3%85%e5%ba%93" class="header-anchor">&lt;/a>下载安装库
&lt;/h2>&lt;p>下载32位glfw二进制包：https://www.glfw.org/download.html
下载glew二进制包：http://glew.sourceforge.net/
上面的两个包下载解压到一个固定目录。&lt;/p>
&lt;h2 id="vs2019配置">&lt;a href="#vs2019%e9%85%8d%e7%bd%ae" class="header-anchor">&lt;/a>VS2019配置
&lt;/h2>&lt;p>添加include目录
&lt;img src="https://pan.2bboy.com/img/2020/05/0531125116.png"
loading="lazy"
>
添加lib目录
&lt;img src="https://pan.2bboy.com/img/2020/05/0531125324.png"
loading="lazy"
>
添加附加依赖项
&lt;img src="https://pan.2bboy.com/img/2020/05/0531125443.png"
loading="lazy"
>&lt;/p>
&lt;h2 id="运行测试">&lt;a href="#%e8%bf%90%e8%a1%8c%e6%b5%8b%e8%af%95" class="header-anchor">&lt;/a>运行测试
&lt;/h2>&lt;p>生成一个窗口&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cpp" data-lang="cpp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#define GLEW_STATIC
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;GL/glew.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;GLFW/glfw3.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">processInput&lt;/span>(GLFWwindow&lt;span style="color:#f92672">*&lt;/span> window) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (glfwGetKey(window, GLFW_KEY_ESCAPE) &lt;span style="color:#f92672">==&lt;/span> GLFW_PRESS) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glfwSetWindowShouldClose(window, true);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glfwInit();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, &lt;span style="color:#ae81ff">3&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, &lt;span style="color:#ae81ff">3&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GLFWwindow&lt;span style="color:#f92672">*&lt;/span> window &lt;span style="color:#f92672">=&lt;/span> glfwCreateWindow(&lt;span style="color:#ae81ff">800&lt;/span>,&lt;span style="color:#ae81ff">600&lt;/span>,&lt;span style="color:#e6db74">&amp;#34;First Window&amp;#34;&lt;/span>,NULL,NULL);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (window &lt;span style="color:#f92672">==&lt;/span> NULL)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> std&lt;span style="color:#f92672">::&lt;/span>cout &lt;span style="color:#f92672">&amp;lt;&amp;lt;&lt;/span> &lt;span style="color:#e6db74">&amp;#34;Failed to create GLFW window&amp;#34;&lt;/span> &lt;span style="color:#f92672">&amp;lt;&amp;lt;&lt;/span> std&lt;span style="color:#f92672">::&lt;/span>endl;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glfwTerminate();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glfwMakeContextCurrent(window);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glewExperimental &lt;span style="color:#f92672">=&lt;/span> true;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (glewInit() &lt;span style="color:#f92672">!=&lt;/span> GLEW_OK) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> std&lt;span style="color:#f92672">::&lt;/span>cout &lt;span style="color:#f92672">&amp;lt;&amp;lt;&lt;/span> &lt;span style="color:#e6db74">&amp;#34;Failed&amp;#34;&lt;/span> &lt;span style="color:#f92672">&amp;lt;&amp;lt;&lt;/span> std&lt;span style="color:#f92672">::&lt;/span>endl;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glfwTerminate();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glViewport(&lt;span style="color:#ae81ff">0&lt;/span>, &lt;span style="color:#ae81ff">0&lt;/span>, &lt;span style="color:#ae81ff">800&lt;/span>, &lt;span style="color:#ae81ff">600&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">while&lt;/span> (&lt;span style="color:#f92672">!&lt;/span>glfwWindowShouldClose(window)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> processInput(window);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glClearColor(&lt;span style="color:#ae81ff">0&lt;/span>, &lt;span style="color:#ae81ff">0.5f&lt;/span>, &lt;span style="color:#ae81ff">0.5f&lt;/span>, &lt;span style="color:#ae81ff">1.0f&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glClear(GL_COLOR_BUFFER_BIT);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glfwSwapBuffers(window);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glfwPollEvents();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glfwTerminate();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="参考">&lt;a href="#%e5%8f%82%e8%80%83" class="header-anchor">&lt;/a>参考
&lt;/h2>&lt;p>&lt;a class="link" href="https://www.bilibili.com/video/BV11W411N7b9" target="_blank" rel="noopener"
>https://www.bilibili.com/video/BV11W411N7b9&lt;/a>&lt;/p></description></item><item><title>Windows编译安装CGAL</title><link>https://kizx.github.io/post/windows%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85cgal/</link><pubDate>Mon, 25 May 2020 18:11:00 +0000</pubDate><guid>https://kizx.github.io/post/windows%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85cgal/</guid><description>&lt;p>CGAL是一个C++计算几何算法库，官方安装说明：https://doc.cgal.org/latest/Manual/windows.html
我的配置是win10+vs2019，已安装有CMake。
[button color=&amp;ldquo;success&amp;rdquo; icon=&amp;ldquo;fa fa-download&amp;rdquo; url=&amp;ldquo;https://pan.2bboy.com/Public/Software/CGAL/&amp;rdquo; type=&amp;quot;&amp;quot;]我用到的所有安装文件[/button]&lt;/p>
&lt;h2 id="下载安装boost">&lt;a href="#%e4%b8%8b%e8%bd%bd%e5%ae%89%e8%a3%85boost" class="header-anchor">&lt;/a>下载安装boost
&lt;/h2>&lt;p>CGAL依赖于boost库，因此需要先安装boost，二进制boost下载地址：https://sourceforge.net/projects/boost/files/boost-binaries/
根据官网说明选择1.17.0版本即可，然后下载具体版本根据vs版本和位数来选择，14.0对应VC2015，14.1对应VC2017，14.2对应VC2019，因此我选择boost_1_71_0-msvc-14.2-64.exe下载即可。
下载解压到硬盘，比如解压到C:\dev\目录下，然后设置环境变量。&lt;/p>
&lt;blockquote>
&lt;ul>
&lt;li>BOOST_LIBRARYDIR = C:\dev\libboost_1_71_0\lib64-msvc-XX.Y&lt;/li>
&lt;li>BOOST_INCLUDEDIR = C:\dev\libboost_1_71_0&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;p>&lt;img src="https://pan.2bboy.com/img/2020/05/0526010253.png"
loading="lazy"
>
最后将&lt;code>C:\dev\libboost_1_71_0\lib64-msvc-XX.Y&lt;/code>添加到系统环境变量&lt;code>PATH&lt;/code>中。&lt;/p>
&lt;hr>
&lt;h3 id="自己编译">&lt;a href="#%e8%87%aa%e5%b7%b1%e7%bc%96%e8%af%91" class="header-anchor">&lt;/a>自己编译
&lt;/h3>&lt;p>如果不直接下载二进制文件，自己来编译也是可以的（我刚开始就这么干的(ー_ー)!!）
下载解压boost源文件：https://sourceforge.net/projects/boost/files/boost-binaries/
解压过程比较慢，解压后得到一堆文件，运行解压目录下的bootstrap.bat文件进行编译。
第一次运行会报下面的错误：&lt;/p>
&lt;pre tabindex="0">&lt;code>&amp;#39;cl&amp;#39; 不是内部或外部命令，也不是可运行的程序或批处理文件。
&lt;/code>&lt;/pre>&lt;p>解决方法是将&lt;code>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\Hostx64\x64&lt;/code>添加到系统变量，然后运行vs的命令行工具&lt;code>x64 Native Tools Command Prompt for VS 2019&lt;/code>(用系统的命令行会报错)，这个命令行不能直接cd切到另一个盘符下，需要先输入&lt;code>d:&lt;/code>切换盘符才行。
然后&lt;code>cd d:\boost\boost_1_66_0&lt;/code>切换到文件目录，输入&lt;code>bootstrap.bat&lt;/code>运行，然后目录下就会生成几个文件，其中有个b2.exe，直接运行会报错。
解决方法是打开&lt;code>project-config.jam&lt;/code>，修改为&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-txt" data-lang="txt">&lt;span style="display:flex;">&lt;span>import option ;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>using msvc : 16.0 : &amp;#34;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\Hostx64\x64\c1.exe&amp;#34;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>option.set keep-going : false ;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>然后输入&lt;code>b2.exe --with-system --with-thread&lt;/code>进行编译，不带后面参数会编译所有库，相当费时间，只编译需要的库就好。
编译好的lib库在&amp;quot;/stage/lib&amp;quot;下，将根目录和lib目录添加到系统变量。&lt;/p>
&lt;h2 id="下载安装cgal">&lt;a href="#%e4%b8%8b%e8%bd%bd%e5%ae%89%e8%a3%85cgal" class="header-anchor">&lt;/a>下载安装CGAL
&lt;/h2>&lt;p>从github上下载CGAL-5.0.2-Setup.exe：https://github.com/CGAL/cgal/releases
点击安装，安装到最后应该会有一个弹窗提醒手动设置环境变量，那就将&lt;code>C:\dev\CGAL-5.0.2\auxiliary\gmp\lib&lt;/code>添加到环境变量&lt;code>PATH&lt;/code>中。&lt;/p>
&lt;h2 id="其他可选依赖">&lt;a href="#%e5%85%b6%e4%bb%96%e5%8f%af%e9%80%89%e4%be%9d%e8%b5%96" class="header-anchor">&lt;/a>其他可选依赖
&lt;/h2>&lt;h3 id="qt">&lt;a href="#qt" class="header-anchor">&lt;/a>Qt
&lt;/h3>&lt;p>下载地址：https://www.qt.io/offline-installers 或 &lt;a class="link" href="http://download.qt.io/official_releases/" target="_blank" rel="noopener"
>http://download.qt.io/official_releases/&lt;/a>
安装时勾选MSVC2017的编译器和Qt Script(有些demo可能会用到)，如果硬盘够大的话，把下面几个Qt都勾了也没什么不好。如果现在不勾选，后面再想安装就会很麻烦，具体方法可以自行百度。
&lt;img src="https://pan.2bboy.com/img/2020/05/0526224650.png"
loading="lazy"
>
完成后添加&lt;code>QTDIR&lt;/code>的系统变量，路径为根目录&lt;code>C:\Qt\Qt5.12.8&lt;/code>，然后添加之前勾选的编译器系统坏境路径&lt;code>C:\Qt\Qt5.12.8\5.12.8\msvc2017_64\bin&lt;/code>到&lt;code>PATH&lt;/code>中。&lt;/p>
&lt;h3 id="eigen">&lt;a href="#eigen" class="header-anchor">&lt;/a>Eigen
&lt;/h3>&lt;p>下载地址：http://eigen.tuxfamily.org/index.php?title=Main_Page&lt;/p>
&lt;h2 id="cmake编译运行">&lt;a href="#cmake%e7%bc%96%e8%af%91%e8%bf%90%e8%a1%8c" class="header-anchor">&lt;/a>Cmake编译运行
&lt;/h2>&lt;p>然后我们按照官网上的说明进入examples\Triangulation_2目录，新建一个build文件夹，然后启动Cmake，设置源文件夹和输出文件夹，如果用下面的命令行启动的话会自动设置好。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cmd" data-lang="cmd">&lt;span style="display:flex;">&lt;span>C:\dev\CGAL-5.0.2&lt;span style="color:#75715e">&amp;gt; cd examples\Triangulation_2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>C:\dev\CGAL-5.0.2\examples\Triangulation_2&lt;span style="color:#75715e">&amp;gt; mkdir build&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>C:\dev\CGAL-5.0.2\examples\Triangulation_2&lt;span style="color:#75715e">&amp;gt; cd build&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>C:\dev\CGAL-5.0.2\examples\Triangulation_2\build&lt;span style="color:#75715e">&amp;gt; cmake-gui ..&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;img src="https://pan.2bboy.com/img/2020/05/0526015343.png"
loading="lazy"
>
点击左下角&lt;code>Configure&lt;/code>进行配置，一般要点两次。
&lt;img src="https://pan.2bboy.com/img/2020/05/0526015403.png"
loading="lazy"
>
继续点击&lt;code>Generate&lt;/code>。
&lt;img src="https://pan.2bboy.com/img/2020/05/0526013040.png"
loading="lazy"
>
生成成功的话在build目录下会生成&lt;code>Triangulation_2_Examples.sln&lt;/code>文件，点击打开或者点击&lt;code>Open Project&lt;/code>也可以直接打开，在vs里生成不报错应该就没问题。
但是直接点击(ctrl)F5会报错无法启动程序，那是因为当前项目是CMake自动生成的ALL_BUILD，需要将别的项目切换为当前项目（不会用vs的我被这个给坑了好久。。。）
&lt;img src="https://pan.2bboy.com/img/2020/05/0526214519.png"
loading="lazy"
>&lt;/p>
&lt;hr>
&lt;p>官网上面是一个编译了一个三角剖分Triangulation的example，运行起来没有什么意思。
其实我们可以对CGAL里的任何一个demo或者example进行编译，当然也可以对整个CGAL文件夹或demo/examples文件夹进行编译，只要文件夹下有CMakeLists.txt文件就能被CMake编译，不过整个编译文件夹容易出错，因为包含了更多的库，可能这些库我们并没有装全，而且全部编译后的工程文件太大对电脑性能要求也更高。
下面是编译demo文件夹后，运行P4HDT2的界面。
&lt;img src="https://pan.2bboy.com/img/2020/05/0526220507.png"
loading="lazy"
>&lt;/p>
&lt;h2 id="参考">&lt;a href="#%e5%8f%82%e8%80%83" class="header-anchor">&lt;/a>参考
&lt;/h2>&lt;p>&lt;a class="link" href="https://blog.csdn.net/u013094443/article/details/51106015" target="_blank" rel="noopener"
>https://blog.csdn.net/u013094443/article/details/51106015&lt;/a>
&lt;a class="link" href="https://blog.csdn.net/s_lisheng/article/details/72871218" target="_blank" rel="noopener"
>https://blog.csdn.net/s_lisheng/article/details/72871218&lt;/a>
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/99814130" target="_blank" rel="noopener"
>https://zhuanlan.zhihu.com/p/99814130&lt;/a>&lt;/p></description></item><item><title>Git常用命令</title><link>https://kizx.github.io/post/git%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/</link><pubDate>Sun, 24 Nov 2019 02:30:00 +0000</pubDate><guid>https://kizx.github.io/post/git%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/</guid><description>&lt;p>&lt;a class="link" href="https://gitee.com/help/categories/43" target="_blank" rel="noopener"
>https://gitee.com/help/categories/43&lt;/a>
&lt;a class="link" href="https://git-scm.com/book/zh/v2/" target="_blank" rel="noopener"
>https://git-scm.com/book/zh/v2/&lt;/a>
&lt;a class="link" href="https://git-scm.com/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E7%94%9F%E6%88%90-SSH-%E5%85%AC%E9%92%A5" target="_blank" rel="noopener"
>https://git-scm.com/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E7%94%9F%E6%88%90-SSH-%E5%85%AC%E9%92%A5&lt;/a>&lt;/p>
&lt;h2 id="初始化">&lt;a href="#%e5%88%9d%e5%a7%8b%e5%8c%96" class="header-anchor">&lt;/a>初始化
&lt;/h2>&lt;pre tabindex="0">&lt;code class="language-git" data-lang="git"># 设置用户信息
git config --global user.name kizx
git config --global user.email kizxmoe@gmail.com
# 查看设置
git config --list
# 生成密钥
ssh-keygen
# 查看公钥
cat ~/.ssh/id_rsa.pub
&lt;/code>&lt;/pre>&lt;h2 id="创建仓库">&lt;a href="#%e5%88%9b%e5%bb%ba%e4%bb%93%e5%ba%93" class="header-anchor">&lt;/a>创建仓库
&lt;/h2>&lt;pre tabindex="0">&lt;code class="language-git" data-lang="git"># 初始化
git init
# 添加所有文件
git add .
# 提交
git commit -m &amp;#34;first commit&amp;#34;
# 添加远程仓库
git remote add origin git@gitee.com:kizx/rime.git
# 推送
git push -u origin master
&lt;/code>&lt;/pre></description></item><item><title>C++酷Q应用开发</title><link>https://kizx.github.io/post/c++%E9%85%B7q%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91/</link><pubDate>Sat, 26 Oct 2019 09:31:00 +0000</pubDate><guid>https://kizx.github.io/post/c++%E9%85%B7q%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91/</guid><description>&lt;p>以前自己的水平不够，这个项目一直搞不懂，现在起码能跑通了，其实也是比较简单的，项目地址：https://github.com/richardchien/coolq-cpp-sdk&lt;/p>
&lt;h2 id="步骤">&lt;a href="#%e6%ad%a5%e9%aa%a4" class="header-anchor">&lt;/a>步骤
&lt;/h2>&lt;p>在该装的东西都装了后，在cmd中依次执行以下命令即可。其中最后一个命令，可能需要先进powershell管理员模式运行&lt;code>Set-ExecutionPolicy&lt;/code>并选择是来打开权限。另外由于网络原因，可能会在Unpacking objects这一步卡住，我是通过加速来解决的。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cmd" data-lang="cmd">&lt;span style="display:flex;">&lt;span>git clone https://github.com/richardchien/coolq-cpp-sdk.git my-awesome-app
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">cd&lt;/span> my-awesome-app
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git submodule init
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git submodule update
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>powershell .\scripts\prepare_prebuilt.ps1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>然后编译项目，把编译出来的相应文件丢进酷Q的dev文件夹里就行了。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cmd" data-lang="cmd">&lt;span style="display:flex;">&lt;span>powershell .\scripts\generate.ps1 Release
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>powershell .\scripts\build.ps1 Release
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Windows下使用make命令</title><link>https://kizx.github.io/post/windows%E4%B8%8B%E4%BD%BF%E7%94%A8make%E5%91%BD%E4%BB%A4/</link><pubDate>Sun, 13 Oct 2019 08:47:03 +0000</pubDate><guid>https://kizx.github.io/post/windows%E4%B8%8B%E4%BD%BF%E7%94%A8make%E5%91%BD%E4%BB%A4/</guid><description>&lt;p>看CMake教程时每次在cmake后都会跟着一个make命令，Linux系统下天然有这个命令。但是我的电脑装了MinGW，也设了环境变量却用不了make命令。&lt;/p>
&lt;h2 id="解决">&lt;a href="#%e8%a7%a3%e5%86%b3" class="header-anchor">&lt;/a>解决
&lt;/h2>&lt;p>先去MinGW的安装目录下的bin目录里看看有没有mingw32-make.exe文件，如果没有用以下命令下载：
&lt;code>mingw-get install gcc g++ mingw32-make&lt;/code>
然后将该文件重命名为make.exe即可。
这样通过CMake利用MinGW编译生成MakeFile相关文件，直接调用make命令就能生成可执行文件了，比起用微软的VS要方便不少。&lt;/p></description></item><item><title>CMake+VS2017编译OpenCV程序</title><link>https://kizx.github.io/post/cmake+vs2017%E7%BC%96%E8%AF%91opencv%E7%A8%8B%E5%BA%8F/</link><pubDate>Fri, 11 Oct 2019 16:27:00 +0000</pubDate><guid>https://kizx.github.io/post/cmake+vs2017%E7%BC%96%E8%AF%91opencv%E7%A8%8B%E5%BA%8F/</guid><description>&lt;p>起因来自下面的OpenCVd官方的一个教程，尝试使用CMake。&lt;/p>
&lt;ul>
&lt;li>&lt;a class="link" href="https://docs.opencv.org/4.1.1/db/df5/tutorial_linux_gcc_cmake.html" target="_blank" rel="noopener"
>https://docs.opencv.org/4.1.1/db/df5/tutorial_linux_gcc_cmake.html&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>但是按照官方的教程会出现很多问题。&lt;/p>
&lt;h2 id="建立工程">&lt;a href="#%e5%bb%ba%e7%ab%8b%e5%b7%a5%e7%a8%8b" class="header-anchor">&lt;/a>建立工程
&lt;/h2>&lt;ul>
&lt;li>先建立下面的这样一个结构
&lt;img src="https://pan.2bboy.com/img/2019/10/1102879862.png"
loading="lazy"
>&lt;/li>
&lt;li>主函数代码&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cpp" data-lang="cpp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;opencv2/core.hpp&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;opencv2/highgui.hpp&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">using&lt;/span> &lt;span style="color:#66d9ef">namespace&lt;/span> cv;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>(&lt;span style="color:#66d9ef">int&lt;/span> argc, &lt;span style="color:#66d9ef">char&lt;/span>&lt;span style="color:#f92672">**&lt;/span> argv )
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Mat image;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> image &lt;span style="color:#f92672">=&lt;/span> imread( &lt;span style="color:#e6db74">&amp;#34;C:&lt;/span>&lt;span style="color:#ae81ff">\\&lt;/span>&lt;span style="color:#e6db74">Users&lt;/span>&lt;span style="color:#ae81ff">\\&lt;/span>&lt;span style="color:#e6db74">ZXIN&lt;/span>&lt;span style="color:#ae81ff">\\&lt;/span>&lt;span style="color:#e6db74">Desktop&lt;/span>&lt;span style="color:#ae81ff">\\&lt;/span>&lt;span style="color:#e6db74">001.png&amp;#34;&lt;/span> );
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> namedWindow(&lt;span style="color:#e6db74">&amp;#34;Display Image&amp;#34;&lt;/span>, WINDOW_AUTOSIZE );
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> imshow(&lt;span style="color:#e6db74">&amp;#34;Display Image&amp;#34;&lt;/span>, image);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> waitKey(&lt;span style="color:#ae81ff">0&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>CMakeLists.txt内容&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-txt" data-lang="txt">&lt;span style="display:flex;">&lt;span>cmake_minimum_required(VERSION 2.8)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>project( DisplayImage )
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>find_package( OpenCV REQUIRED )
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>add_executable( DisplayImage DisplayImage.cpp )
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>target_link_libraries( DisplayImage ${OpenCV_LIBS} )
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="编译">&lt;a href="#%e7%bc%96%e8%af%91" class="header-anchor">&lt;/a>编译
&lt;/h2>&lt;ul>
&lt;li>如果在命令行cmake的话会找不到路径，所以我改用CMake GUI，先选择CMakeLists所在文件夹和编译后的一个空文件夹
&lt;img src="https://pan.2bboy.com/img/2019/10/1024986576.png"
loading="lazy"
>&lt;/li>
&lt;li>点击Configure，按下图配置，点击Finish
&lt;img src="https://pan.2bboy.com/img/2019/10/2555629652.png"
loading="lazy"
>&lt;/li>
&lt;li>这是应该会报错，这是就体现gui的方便之处了，点击替换正确的OpenCV路径
&lt;img src="https://pan.2bboy.com/img/2019/10/2692616696.png"
loading="lazy"
>
&lt;img src="https://pan.2bboy.com/img/2019/10/889438698.png"
loading="lazy"
>&lt;/li>
&lt;li>如果还有报错的话，建议gui左上角清除CMake缓存重新开始，没有问题的话继续点击Generate和Open Project，软件自动打开build下的VS工程文件，VS里右键生成解决方案即可。&lt;/li>
&lt;/ul></description></item><item><title>OpenCV + Qt 配置</title><link>https://kizx.github.io/post/opencv--+-qt-%E9%85%8D%E7%BD%AE/</link><pubDate>Mon, 07 Oct 2019 14:20:00 +0000</pubDate><guid>https://kizx.github.io/post/opencv--+-qt-%E9%85%8D%E7%BD%AE/</guid><description>&lt;p>假设已经下载安装了OpenCV和Qt并且配置好了OpenCV的环境变量，环境变量设置可以参考以前的文章。&lt;/p>
&lt;h2 id="cmake编译">&lt;a href="#cmake%e7%bc%96%e8%af%91" class="header-anchor">&lt;/a>CMake编译
&lt;/h2>&lt;p>许多教程都会从CMake编译OpenCV开始，但其实我们下载的安装包解压后已经编译好了，bulid文件下就是编译后的文件，除非有特殊要求，可以不用亲自编译。主要是我尝试用CMake编译Source但是报错失败了，就此作罢。&lt;/p>
&lt;h2 id="编写pri文件">&lt;a href="#%e7%bc%96%e5%86%99pri%e6%96%87%e4%bb%b6" class="header-anchor">&lt;/a>编写pri文件
&lt;/h2>&lt;p>新建一个文件，重命名为&lt;code>opencv.pri&lt;/code>，写入以下内容，其实和在VS2017里配置库环境是一样的道理。&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-pri" data-lang="pri">INCLUDEPATH += c:/opencv/build/include
Debug: {
LIBS += -lc:/opencv/build/x64/vc15/lib/opencv_world411d
}
Release: {
LIBS += -lc:/opencv/build/x64/vc15/lib/opencv_world411
}
&lt;/code>&lt;/pre>&lt;h2 id="新建工程">&lt;a href="#%e6%96%b0%e5%bb%ba%e5%b7%a5%e7%a8%8b" class="header-anchor">&lt;/a>新建工程
&lt;/h2>&lt;p>在Qt里新建一个最普通的工程，编译器选择VS2017 64bit，新建完成后在工程的pro文件最后添加刚才的pri文件路径：
&lt;code>include(c:/opencv/opencv.pri)&lt;/code>&lt;/p>
&lt;h2 id="测试代码">&lt;a href="#%e6%b5%8b%e8%af%95%e4%bb%a3%e7%a0%81" class="header-anchor">&lt;/a>测试代码
&lt;/h2>&lt;p>在main函数里进行测试&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cpp" data-lang="cpp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;#34;mainwindow.h&amp;#34;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;QApplication&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;#34;opencv2/opencv.hpp&amp;#34;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>(&lt;span style="color:#66d9ef">int&lt;/span> argc, &lt;span style="color:#66d9ef">char&lt;/span> &lt;span style="color:#f92672">*&lt;/span>argv[])
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> QApplication a(argc, argv);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">using&lt;/span> &lt;span style="color:#66d9ef">namespace&lt;/span> cv;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Mat img &lt;span style="color:#f92672">=&lt;/span> imread(&lt;span style="color:#e6db74">&amp;#34;../001.png&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> imshow(&lt;span style="color:#e6db74">&amp;#34;TEST&amp;#34;&lt;/span>,img);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> waitKey(&lt;span style="color:#ae81ff">0&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> a.exec();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>OpenCV + Visual Studio2017 配置</title><link>https://kizx.github.io/post/opencv-+-visual-studio2017-%E9%85%8D%E7%BD%AE/</link><pubDate>Wed, 11 Sep 2019 17:25:00 +0000</pubDate><guid>https://kizx.github.io/post/opencv-+-visual-studio2017-%E9%85%8D%E7%BD%AE/</guid><description>&lt;h2 id="1-下载安装opencv并添加环境变量">&lt;a href="#1-%e4%b8%8b%e8%bd%bd%e5%ae%89%e8%a3%85opencv%e5%b9%b6%e6%b7%bb%e5%8a%a0%e7%8e%af%e5%a2%83%e5%8f%98%e9%87%8f" class="header-anchor">&lt;/a>1. 下载安装OpenCV并添加环境变量
&lt;/h2>&lt;p>下载地址：https://opencv.org/releases/
安装参考：http://c.biancheng.net/view/1104.html
我安装的是Opencv4.1.1版本，然后管理员cmd命令添加环境变量，其实不用命令手动添加也行,不过这一步似乎不是必须的，但可能会与某些步骤有关联。
&lt;code>setx -m OPENCV_DIR C:\opencv\build\x64\vc15&lt;/code>
&lt;img src="https://pan.2bboy.com/img/2019/10/3652238186.png"
loading="lazy"
>
&lt;img src="https://pan.2bboy.com/img/2019/10/4000912026.png"
loading="lazy"
>
然后添加以下OpenCV环境变量到PATH中，VS2017应该对应的是vc15，不过都加进去也不会出错。路径直接填%OPENCV_DIR%\bin也行。
&lt;code>C:\opencv\build\x64\vc14\bin&lt;/code>
&lt;code>C:\opencv\build\x64\vc15\bin&lt;/code>&lt;/p>
&lt;h2 id="2-新建工程">&lt;a href="#2-%e6%96%b0%e5%bb%ba%e5%b7%a5%e7%a8%8b" class="header-anchor">&lt;/a>2. 新建工程
&lt;/h2>&lt;p>打开vs2017，新建控制台程序，将系统平台改成64位，在项目上右键属性配置下列项目&lt;/p>
&lt;ul>
&lt;li>
&lt;p>点击VC++目录-&amp;gt;包含目录，添加include文件夹目录
&lt;img src="https://pan.2bboy.com/img/2019/10/20190912174155.png"
loading="lazy"
>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>点击VC++目录-&amp;gt;库目录，添加lib文件夹目录
&lt;img src="https://pan.2bboy.com/img/2019/10/20190912174251.png"
loading="lazy"
>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>点击链接库-&amp;gt;输入-&amp;gt;附加项，添加lib，其中opencv_world411d.lib为debug模式用的，opencv_world411.lib为release模式用的，都可以在lib文件夹下找到
&lt;img src="https://pan.2bboy.com/img/2019/10/20190912174625.png"
loading="lazy"
>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="3-测试代码">&lt;a href="#3-%e6%b5%8b%e8%af%95%e4%bb%a3%e7%a0%81" class="header-anchor">&lt;/a>3. 测试代码
&lt;/h2>&lt;p>打开一张图片进行测试&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cpp" data-lang="cpp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;opencv2/core.hpp&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;opencv2/highgui.hpp&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">using&lt;/span> &lt;span style="color:#66d9ef">namespace&lt;/span> cv;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Mat img &lt;span style="color:#f92672">=&lt;/span> imread(&lt;span style="color:#e6db74">&amp;#34;C:&lt;/span>&lt;span style="color:#ae81ff">\\&lt;/span>&lt;span style="color:#e6db74">Users&lt;/span>&lt;span style="color:#ae81ff">\\&lt;/span>&lt;span style="color:#e6db74">ZXIN&lt;/span>&lt;span style="color:#ae81ff">\\&lt;/span>&lt;span style="color:#e6db74">Desktop&lt;/span>&lt;span style="color:#ae81ff">\\&lt;/span>&lt;span style="color:#e6db74">cv&lt;/span>&lt;span style="color:#ae81ff">\\&lt;/span>&lt;span style="color:#e6db74">001.png&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> imshow(&lt;span style="color:#e6db74">&amp;#34;001&amp;#34;&lt;/span>, img);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> waitKey(&lt;span style="color:#ae81ff">0&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>加速Python的几种方法</title><link>https://kizx.github.io/post/%E5%8A%A0%E9%80%9Fpython%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E6%B3%95/</link><pubDate>Sun, 04 Aug 2019 17:12:00 +0000</pubDate><guid>https://kizx.github.io/post/%E5%8A%A0%E9%80%9Fpython%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E6%B3%95/</guid><description>&lt;h2 id="前言">&lt;a href="#%e5%89%8d%e8%a8%80" class="header-anchor">&lt;/a>前言
&lt;/h2>&lt;p>&lt;em>注意以下内容均为本人主观操作感受，运行环境为Win10+python3.7_32位，仅供本人日后查阅&lt;/em>&lt;/p>
&lt;p>众所周知，python是一门优美而简洁的编程语言，其最大的不足在于运行速度过于感人，而C语言作为最接近底层的高级语言，速度快是他最大的优势。python被誉为胶水语言，应该有办法和C语言胶和起来，我查阅资料发现python调用C语言最普遍的方式大概有三种：&lt;/p>
&lt;ol>
&lt;li>将C语言的函数编译成dll动态链接库，然后通过python的ctypes模块对dll进行调用。&lt;/li>
&lt;li>借由cython先将python代码编译成C语言代码，然后再讲C代码编译成.pyd文件直接在python中导入进行调用，cython本身有一定语法，不过不会一般也不太影响使用。&lt;/li>
&lt;li>使用Swig可以将C代码直接封装成python代码，过程略为复杂，优点是可以为多种语言提供接口。&lt;/li>
&lt;/ol>
&lt;p>以上几种方法的原理和过程下图很好的解释了：&lt;/p>
&lt;p>&lt;img src="https://pan.2bboy.com/img/2019/10/20190907022654.png"
loading="lazy"
alt="图片来自网络"
>&lt;/p>
&lt;p>本文以斐波拉契函数为例，探究python和C的合璧之法。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Python" data-lang="Python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> time
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">def&lt;/span> &lt;span style="color:#a6e22e">fib&lt;/span>(n):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> n &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">elif&lt;/span> n &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">else&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> fib(n&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>) &lt;span style="color:#f92672">+&lt;/span> fib(n&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">2&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>start&lt;span style="color:#f92672">=&lt;/span>time&lt;span style="color:#f92672">.&lt;/span>time()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>print(&lt;span style="color:#e6db74">&amp;#34;计算结果:&lt;/span>&lt;span style="color:#e6db74">%d&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">%&lt;/span> fib(&lt;span style="color:#ae81ff">40&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>end&lt;span style="color:#f92672">=&lt;/span>time&lt;span style="color:#f92672">.&lt;/span>time()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>print(&lt;span style="color:#e6db74">&amp;#39;python time cost:&amp;#39;&lt;/span>,end&lt;span style="color:#f92672">-&lt;/span>start)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;stdio.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;stdlib.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;time.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">fib&lt;/span>(&lt;span style="color:#66d9ef">int&lt;/span> n)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (n &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">else&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> (n &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">else&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">fib&lt;/span>(n &lt;span style="color:#f92672">-&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>) &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#a6e22e">fib&lt;/span>(n &lt;span style="color:#f92672">-&lt;/span> &lt;span style="color:#ae81ff">2&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">clock_t&lt;/span> start, end;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> start &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">clock&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;计算结果:%d&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">fib&lt;/span>(&lt;span style="color:#ae81ff">40&lt;/span>));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> end &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">clock&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;C cost time:%f&amp;#34;&lt;/span>, (&lt;span style="color:#66d9ef">double&lt;/span>)(end &lt;span style="color:#f92672">-&lt;/span> start) &lt;span style="color:#f92672">/&lt;/span> CLOCKS_PER_SEC);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">system&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;pause&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>通过运行上面的代码可以得到运行时间：&lt;/p>
&lt;blockquote>
&lt;ul>
&lt;li>纯python：&lt;br>
计算结果:102334155&lt;br>
python time cost: 87.49325394630432&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;blockquote>
&lt;ul>
&lt;li>纯C语言：&lt;br>
计算结果:102334155&lt;br>
C cost time:0.863000&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;p>差不多差了两个数量级吧。。。&lt;/p>
&lt;h2 id="1-通过ctypes调用dll">&lt;a href="#1-%e9%80%9a%e8%bf%87ctypes%e8%b0%83%e7%94%a8dll" class="header-anchor">&lt;/a>1. 通过ctypes调用dll
&lt;/h2>&lt;p>首先得先生成一个dll，你可以在ide里新建一个dll工程进行创建。更简单的做法是利用下面的gcc命令直接在cmd里进行编译，但前提是你已经装了Mingw或者并Mingw-w64且设置了环境变量，其中有个比较坑的地方就是你编译出来的dll位数要和你的python位数要匹配，像我笔记本上装的是Mingw-w64，而pyhton是32位的，32的python无法调用64位的dll，而这位Mingw-w64虽说同时支持64位和32位，但是前提是安装时勾选的是sjlj而不是seh，seh不支持32位！&lt;/p>
&lt;ul>
&lt;li>
&lt;p>安装Mingw建议用下面这位up的工具，简单快捷。&lt;br>
&lt;a class="link" href="https://www.bilibili.com/video/av52434248" target="_blank" rel="noopener"
>【一键】20秒配置VScodeC语言C++开发环境！&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>安装Mingw-w64可以参考：&lt;a class="link" href="https://www.cnblogs.com/ggg-327931457/p/9694516.html" target="_blank" rel="noopener"
>Mingw-w64安装&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>用于编译dll的c语言代码只需给出函数就好了：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">fib&lt;/span>(&lt;span style="color:#66d9ef">int&lt;/span> n)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span>(n &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">else&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span>(n &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">else&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">fib&lt;/span>(n&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>) &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#a6e22e">fib&lt;/span>(n&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">2&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>下面是cmd中将C原文件编译成dll的命令：&lt;/p>
&lt;pre tabindex="0">&lt;code>gcc -fPIC -shared name.c -o name.dll
&lt;/code>&lt;/pre>&lt;p>如果是sjlj的Mingw-w64加上-m32可以编译出32位dll：&lt;/p>
&lt;pre tabindex="0">&lt;code>gcc -fPIC -shared -m32?name.c -o?name.dll
&lt;/code>&lt;/pre>&lt;p>然后在python中导入ctypes模块就可以调用dll了：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> ctypes
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> time
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>start&lt;span style="color:#f92672">=&lt;/span>time&lt;span style="color:#f92672">.&lt;/span>time()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>fibpy&lt;span style="color:#f92672">=&lt;/span>ctypes&lt;span style="color:#f92672">.&lt;/span>CDLL(&lt;span style="color:#e6db74">&amp;#39;fibpy.dll&amp;#39;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>print(&lt;span style="color:#e6db74">&amp;#34;计算结果:&lt;/span>&lt;span style="color:#e6db74">%d&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">%&lt;/span> fibpy&lt;span style="color:#f92672">.&lt;/span>fib(&lt;span style="color:#ae81ff">40&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>end&lt;span style="color:#f92672">=&lt;/span>time&lt;span style="color:#f92672">.&lt;/span>time()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>print(&lt;span style="color:#e6db74">&amp;#39;dll time cost:&amp;#39;&lt;/span>,end&lt;span style="color:#f92672">-&lt;/span>start)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>ctype调用dll运行时间：&lt;/p>
&lt;blockquote>
&lt;ul>
&lt;li>计算结果:102334155&lt;/li>
&lt;li>dll time cost: 0.9999649524688721&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;p>因为只有一个函数，还调用的是C语言的，所以速度和纯C差不多。&lt;/p>
&lt;h2 id="2-cython">&lt;a href="#2-cython" class="header-anchor">&lt;/a>2. cython
&lt;/h2>&lt;p>先给出官方的一个教程：&lt;a class="link" href="http://docs.cython.org/en/latest/src/tutorial/cython_tutorial.html" target="_blank" rel="noopener"
>官方教程&lt;/a>&lt;/p>
&lt;p>使用cython首先要安装cython模块：&lt;/p>
&lt;pre tabindex="0">&lt;code>pip install Cython
&lt;/code>&lt;/pre>&lt;p>然后你需要安装Mingw进行一番配置或者直接下载安装Visual Studio安装C++环境，因为我用的是Mingw-win64，所以自然就先抛弃后面那个巨无霸选用前者，一番尝试后发现还是Visual Studio真香。当然可能单纯的是因为Mingw-win64不支持而已，用Mingw的话应该是可以的（但愿）。&lt;/p>
&lt;p>安装完环境后就可以直接把之前的纯python代码中的函数部分进行cython转换，不过需要现将其后缀名改为.pyx，然后需要再创建一个setup.py文件，其中写入代码：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">from&lt;/span> distutils.core &lt;span style="color:#f92672">import&lt;/span> setup
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">from&lt;/span> Cython.Build &lt;span style="color:#f92672">import&lt;/span> cythonize
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>setup(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">?&lt;/span> &lt;span style="color:#960050;background-color:#1e0010">?&lt;/span> ext_modules &lt;span style="color:#f92672">=&lt;/span> cythonize(&lt;span style="color:#e6db74">&amp;#34;fibcy.pyx&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>然后还是cmd中执行：&lt;/p>
&lt;pre tabindex="0">&lt;code>python setup.py build_ext --inplace
&lt;/code>&lt;/pre>&lt;p>这时应该会生成一个.pyd文件，这个文件本质和前面的dll应该差不多，可以通过import在python中使用：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> time
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> fibcy
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>start&lt;span style="color:#f92672">=&lt;/span>time&lt;span style="color:#f92672">.&lt;/span>time()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>print(&lt;span style="color:#e6db74">&amp;#34;计算结果:&lt;/span>&lt;span style="color:#e6db74">%d&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">%&lt;/span> fibcy&lt;span style="color:#f92672">.&lt;/span>fib(&lt;span style="color:#ae81ff">40&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>end&lt;span style="color:#f92672">=&lt;/span>time&lt;span style="color:#f92672">.&lt;/span>time()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>print(&lt;span style="color:#e6db74">&amp;#39;cython time cost:&amp;#39;&lt;/span>,end&lt;span style="color:#f92672">-&lt;/span>start)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>运行结果：&lt;/p>
&lt;blockquote>
&lt;ul>
&lt;li>计算结果:102334155&lt;/li>
&lt;li>cython time cost: 15.108871698379517&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;p>可以看到即使是在没有使用任何cython语法的情况下，cython的加速能力也是令人惊叹的，运行速度提高了一个数量级左右！&lt;/p>
&lt;h2 id="3-swig">&lt;a href="#3-swig" class="header-anchor">&lt;/a>3. Swig
&lt;/h2>&lt;p>同样先给出一个教程参考：&lt;a class="link" href="https://www.jianshu.com/p/ccd239bd11d9" target="_blank" rel="noopener"
>Swig教程&lt;/a>&lt;/p>
&lt;p>其实swig的原理和前面也差不多，但是过程更为复杂。首先当然要安装swig，下载解压后同样添加到系统环境变量。&lt;/p>
&lt;p>然后要准备的有C语言源文件，一个.i文件，还有一个setup.py文件。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;stdio.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">fib&lt;/span>(&lt;span style="color:#66d9ef">int&lt;/span> n)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (n &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">else&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> (n &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">else&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">fib&lt;/span>(n &lt;span style="color:#f92672">-&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>) &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#a6e22e">fib&lt;/span>(n &lt;span style="color:#f92672">-&lt;/span> &lt;span style="color:#ae81ff">2&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">%&lt;/span>module fib
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">%&lt;/span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;stdio.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#f92672">%&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">extern&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#a6e22e">fib&lt;/span>(&lt;span style="color:#66d9ef">int&lt;/span> n);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">from&lt;/span> setuptools &lt;span style="color:#f92672">import&lt;/span> setup,Extension
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>setup( name&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#39;fib&amp;#39;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> version&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#39;1.0&amp;#39;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ext_modules&lt;span style="color:#f92672">=&lt;/span>[Extension(&lt;span style="color:#e6db74">&amp;#39;_fib&amp;#39;&lt;/span>, [&lt;span style="color:#e6db74">&amp;#39;fib.c&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;fib.i&amp;#39;&lt;/span>])]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> )
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>最后在命令行运行setup.py：&lt;/p>
&lt;pre tabindex="0">&lt;code>python setup.py build_ext --inplace
&lt;/code>&lt;/pre>&lt;p>最后生成的文件中应该有一个python文件，可以直接进行调用，除此之外我发现还有一个.pyd文件，果然和前面的方法都差不多呢，导入运行方法也和之前相同。&lt;/p>
&lt;p>运行结果：&lt;/p>
&lt;blockquote>
&lt;ul>
&lt;li>计算结果:102334155&lt;/li>
&lt;li>swig time cost: 0.6825790405273438&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;p>居然比纯C语言还要快！大概是因为去掉了计时模块的缘故，可能python的计时模块比C的要快？结果还是很匪夷所思呢？&lt;/p>
&lt;h2 id="4-namba的jit加速">&lt;a href="#4-namba%e7%9a%84jit%e5%8a%a0%e9%80%9f" class="header-anchor">&lt;/a>4. namba的@jit加速
&lt;/h2>&lt;p>namba加速不同于以上3种方法，上面3种方法多多少少会和C语言扯上点关系。numba则是直接在python源文件里通过加上一些代码直接运行并获得加速效果，本质原理也是使数据向静态靠拢，但是实现过程与上面3种方法相比更简单，可以参考&lt;a class="link" href="http://numba.pydata.org/numba-doc/latest/user/5minguide.html" target="_blank" rel="noopener"
>官方入门教程&lt;/a>&lt;/p>
&lt;p>下面具体看一下实现过程：
首先肯定是要先安装numba包&lt;/p>
&lt;pre tabindex="0">&lt;code>pip install numba
&lt;/code>&lt;/pre>&lt;p>然后只需在Python代码中导入numba并用jit修饰相应的函&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> time
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">from&lt;/span> numba &lt;span style="color:#f92672">import&lt;/span> jit
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">@jit&lt;/span>(nopython&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#66d9ef">True&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">def&lt;/span> &lt;span style="color:#a6e22e">fib&lt;/span>(n):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> n &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">elif&lt;/span> n &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">else&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> fib(n&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>) &lt;span style="color:#f92672">+&lt;/span> fib(n&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">2&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>start&lt;span style="color:#f92672">=&lt;/span>time&lt;span style="color:#f92672">.&lt;/span>time()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>print(&lt;span style="color:#e6db74">&amp;#34;计算结果:&lt;/span>&lt;span style="color:#e6db74">%d&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">%&lt;/span> fib(&lt;span style="color:#ae81ff">40&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>end&lt;span style="color:#f92672">=&lt;/span>time&lt;span style="color:#f92672">.&lt;/span>time()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>print(&lt;span style="color:#e6db74">&amp;#39;numba@jit time cost:&amp;#39;&lt;/span>,end&lt;span style="color:#f92672">-&lt;/span>start)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>运行结果：&lt;/p>
&lt;blockquote>
&lt;ul>
&lt;li>计算结果:102334155&lt;/li>
&lt;li>numba@jit time cost: 1.2832109928131104&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;p>加速效果可以说是相当惊人的，比cython要快，而且操作也特别简单，不用导来导去，和numpy相配合使用可以使运行速度得到极大的提升。&lt;/p>
&lt;h2 id="总结">&lt;a href="#%e6%80%bb%e7%bb%93" class="header-anchor">&lt;/a>总结
&lt;/h2>&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align: center">方案&lt;/th>
&lt;th style="text-align: center">运行时间&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align: center">纯Python&lt;/td>
&lt;td style="text-align: center">87.49325394630432&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align: center">纯C语言&lt;/td>
&lt;td style="text-align: center">0.863000&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align: center">ctypes&lt;/td>
&lt;td style="text-align: center">0.9999649524688721&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align: center">cython&lt;/td>
&lt;td style="text-align: center">15.108871698379517&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align: center">swig&lt;/td>
&lt;td style="text-align: center">0.6825790405273438&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align: center">numba&lt;/td>
&lt;td style="text-align: center">1.2832109928131104&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>python结合c语言的三种方法中ctypes方法最简单，将C代码直接编译成dll即可使用，cython可以为现有的python代码加速，swig可以直接将C转换为python，就是有点麻烦，但速度是最快的。numba的jit加速比上面三种方法都要更简单，只需在python源码里加几句就行了，而且速度也很可观。&lt;/p></description></item></channel></rss>