<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Topics tagged with c++17]]></title><description><![CDATA[A list of topics that have been tagged with c++17]]></description><link>http://forum.d2learn.org/tags/c++17</link><generator>RSS for Node</generator><lastBuildDate>Wed, 12 Aug 2026 02:46:34 GMT</lastBuildDate><atom:link href="http://forum.d2learn.org/tags/c++17.rss" rel="self" type="application/rss+xml"/><pubDate>Invalid Date</pubDate><ttl>60</ttl><item><title><![CDATA[在linux环境下创建C++ drogon 项目 进行接口测试(项目推动型学习)]]></title><description><![CDATA[<p dir="auto">​</p>
<p dir="auto">项目简单（仅为学习）<br />
我并不是很会这个框架 还在学习中<br />
环境准备（Ubuntu 22.04）</p>
<pre><code>gcc --version
</code></pre>
<p dir="auto">检查当前GCC版本：<br />
gcc --version<br />
<img src="/assets/uploads/files/1770194231828-e89ff7bd-b51b-4307-a36d-1633946d9aed-image.png" alt="e89ff7bd-b51b-4307-a36d-1633946d9aed-image.png" class=" img-fluid img-markdown" /><br />
​​</p>
<p dir="auto">图1-1(C++版本查询)</p>
<pre><code>g++ -v --help 2&gt;&amp;1 | grep "std="
</code></pre>
<p dir="auto">若版本低于9.0，需执行以下升级操作：</p>
<pre><code>sudo apt update &amp;&amp; sudo apt upgrade -y
sudo apt install build-essential git cmake -y
sudo apt install gcc-10 g++-10 -y
</code></pre>
<p dir="auto">验证C++17支持：</p>
<pre><code>g++ -v --help 2&gt;&amp;1 | grep "std="
</code></pre>
<p dir="auto">输出应包含gnu++17或c++17 例如:<br />
<img src="/assets/uploads/files/1770194812553-44588389-29ae-4f9f-b77a-a2b05a787e30-image-resized.png" alt="44588389-29ae-4f9f-b77a-a2b05a787e30-image.png" class=" img-fluid img-markdown" /></p>
<p dir="auto"><img src="/assets/uploads/files/1770194868256-3a1a02a9-8c7a-4c3f-a283-df44d21f8e0e-image-resized.png" alt="3a1a02a9-8c7a-4c3f-a283-df44d21f8e0e-image.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">MySQL依赖安装（）</p>
<p dir="auto">安装MariaDB开发库drogon：</p>
<pre><code>sudo apt install -y libmariadb-dev
</code></pre>
<p dir="auto">创建源码目录并克隆仓库：</p>
<pre><code>mkdir drogon_src &amp;&amp; cd drogon_src
git clone https://github.com/drogonframework/drogon
</code></pre>
<p dir="auto">编译安装：</p>
<pre><code>cd drogon
mkdir build &amp;&amp; cd build
cmake ..
</code></pre>
<p dir="auto">初次编译可能会遇到缺失trantor 子模块（Drogon 的网络库依赖）没有被正确下载或初始化。<br />
<img src="/assets/uploads/files/1770195243138-118d02d3-c6b4-48bf-b7aa-23320874463a-image-resized.png" alt="118d02d3-c6b4-48bf-b7aa-23320874463a-image.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">笔者解决办法为：</p>
<pre><code># 进入 Drogon 源码根目录
cd ~/drogon/drogon
</code></pre>
<pre><code># 初始化并更新所有子模块
git submodule update --init --recursive
</code></pre>
<p dir="auto">编译</p>
<h1>编译安装 （nproc）调用当前可用核心数用于编译</h1>
<pre><code>make -j$(nproc)
</code></pre>
<p dir="auto">等待编译：<br />
<img src="/assets/uploads/files/1770195498278-3e65e501-04c1-4834-a887-5dceac785151-image-resized.png" alt="3e65e501-04c1-4834-a887-5dceac785151-image.png" class=" img-fluid img-markdown" /><br />
环境验证<br />
验证drogon 是否安装成功 出现以下版本信息即可。<br />
<img src="/assets/uploads/files/1770195538195-dd1d52ba-a9af-4ac2-a3e2-3e7050a5d9fa-image-resized.png" alt="dd1d52ba-a9af-4ac2-a3e2-3e7050a5d9fa-image.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">*** 使用drogon_ctl创建项目。**<br />
         <br />
        在自己喜欢的文件夹中创建项目</p>
<p dir="auto"><img src="/assets/uploads/files/1770195648710-6369b916-ea68-47b6-8df7-b4b0ae4a5af7-image.png" alt="6369b916-ea68-47b6-8df7-b4b0ae4a5af7-image.png" class=" img-fluid img-markdown" /></p>
<pre><code>drogon_ctl create project Hello-drogon
cd Hello-drogon
</code></pre>
<p dir="auto">进入Hello-drogon的controllers 中在终端新建一个控制器。</p>
<pre><code>#drogon_ctl create controller [参数] [控制器名(自定义)] 
drogon_ctl create controller -h drogonpic
</code></pre>
<p dir="auto"><img src="/assets/uploads/files/1770196352685-561bc505-8380-471c-b7cb-411941a64b8e-image-resized.png" alt="561bc505-8380-471c-b7cb-411941a64b8e-image.png" class=" img-fluid img-markdown" /><br />
编写测试接口<br />
<img src="/assets/uploads/files/1770196229170-23d96a12-94d0-4475-8af6-12fde87bad74-image.png" alt="23d96a12-94d0-4475-8af6-12fde87bad74-image.png" class=" img-fluid img-markdown" /><br />
编写一个简单的接口，该接口包含两个方法 路径为“api/pic”，“api/hello”,仅仅返回"hello drogon"的字符<br />
drogonpic.h 代码：</p>
<p dir="auto">// drogonpic.h 头文件编写。</p>
<pre><code>#pragma once

#include &lt;drogon/HttpController.h&gt;

using namespace drogon;

class drogonpic : public drogon::HttpController&lt;drogonpic&gt;
{
public:
    METHOD_LIST_BEGIN
        // 确保类名正确
        ADD_METHOD_TO(drogonpic::getPic, "/api/pic", Get);
        ADD_METHOD_TO(drogonpic::hello, "/api/hello", Get);
    METHOD_LIST_END
    //hello world 
     void hello(const HttpRequestPtr&amp; req,
                std::function&lt;void(const HttpResponsePtr&amp;)&gt;&amp;&amp; callback) const;

    // 图片获取方法
    void getPic(const HttpRequestPtr&amp; req,
                std::function&lt;void(const HttpResponsePtr&amp;)&gt;&amp;&amp; callback) const;
    
};
</code></pre>
<p dir="auto"><a href="http://xn--drogonpic-uo4qg23s.cc" rel="nofollow ugc">实现drogonpic.cc</a></p>
<pre><code>#include "drogonpic.h"
#include &lt;drogon/HttpResponse.h&gt;
#include &lt;drogon/drogon.h&gt; // 添加日志支持
#include &lt;sys/stat.h&gt;

using namespace drogon;

void drogonpic::getPic(const HttpRequestPtr&amp; req,
                       std::function&lt;void(const HttpResponsePtr&amp;)&gt;&amp;&amp; callback) const
{
    // 使用绝对路径更可靠
    const std::string imagePath = "/home/xhm/xhm/Drogon-Project/Hello-drogon/assets/pic2.png";
    
    // 记录路径信息（调试用）
    LOG_INFO &lt;&lt; "Attempting to load image: " &lt;&lt; imagePath;
    
    // 检查文件是否存在
    struct stat buffer;
    if (stat(imagePath.c_str(), &amp;buffer) != 0) 
    {
        LOG_ERROR &lt;&lt; "Image not found: " &lt;&lt; imagePath;
        auto resp = HttpResponse::newHttpResponse();
        resp-&gt;setStatusCode(k404NotFound);
        resp-&gt;setBody("Image not found");
        callback(resp);
        return;
    }

    // 创建文件响应
    auto resp = HttpResponse::newFileResponse(imagePath, "", CT_IMAGE_PNG);
    
    if (!resp) 
    {
        LOG_ERROR &lt;&lt; "Failed to open image: " &lt;&lt; imagePath;
        resp = HttpResponse::newHttpResponse();
        resp-&gt;setStatusCode(k500InternalServerError);
        resp-&gt;setBody("Failed to open image");
    }
    else 
    {
        LOG_INFO &lt;&lt; "Image loaded successfully: " &lt;&lt; imagePath;
    }
    
    callback(resp);
}



        // 处理GET请求的方法
        void drogonpic::hello(const HttpRequestPtr&amp; req,
            std::function&lt;void(const HttpResponsePtr&amp;)&gt;&amp;&amp; callback) const
    {
        // 创建HTTP响应对象
        auto resp = HttpResponse::newHttpResponse();

        // 设置响应内容
        resp-&gt;setBody("hello world");

        // 设置响应状态码（可选，默认200）
        // resp-&gt;setStatusCode(k200OK);

        // 通过回调返回响应
        callback(resp);
    }
</code></pre>
<p dir="auto">对接口进行测试<br />
对api/hello 测试 使用apipost 进行测试 测试结果如下图所示：ip地址为linux主机的ip</p>
<p dir="auto">网页访问：<br />
<img src="/assets/uploads/files/1770194370743-04bb82cd-049f-4665-9037-9c5c44598877-image.png" alt="04bb82cd-049f-4665-9037-9c5c44598877-image.png" class=" img-fluid img-markdown" /><br />
<img src="/assets/uploads/files/1770194348828-a8f35a9d-29d1-4a3c-ae98-4c4a87e71c1d-image-resized.png" alt="a8f35a9d-29d1-4a3c-ae98-4c4a87e71c1d-image.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">压测结果：</p>
<p dir="auto">对api/pic 测试 给接口是返回一张图片<br />
<img src="/assets/uploads/files/1770194340423-dd3fe72b-3b64-4e04-8786-84498286286f-image-resized.png" alt="dd3fe72b-3b64-4e04-8786-84498286286f-image.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">网页访问：<br />
<img src="/assets/uploads/files/1770195692035-8ebacd02-fef5-4cfa-bbc5-61f575de4198-image.png" alt="8ebacd02-fef5-4cfa-bbc5-61f575de4198-image.png" class=" img-fluid img-markdown" /><br />
压测结果：</p>
<p dir="auto"><img src="/assets/uploads/files/1770194311493-149852d2-c08d-466d-9d7e-c00547fa34ce-image-resized.png" alt="149852d2-c08d-466d-9d7e-c00547fa34ce-image.png" class=" img-fluid img-markdown" /><br />
总结</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>：</th>
<th>C++特性</th>
<th>代码示例</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>#pragma once</code></td>
<td><code>#pragma once</code></td>
</tr>
<tr>
<td>CRTP模板继承</td>
<td><code>class X : public drogon::HttpController&lt;X&gt;</code></td>
</tr>
<tr>
<td><code>auto</code> 自动推导</td>
<td><code>auto resp = HttpResponse::newHttpResponse();</code></td>
</tr>
<tr>
<td>右值引用 <code>&amp;&amp;</code></td>
<td><code>std::function&lt;void(const T&amp;)&gt;&amp;&amp; callback</code></td>
</tr>
<tr>
<td><code>std::function</code></td>
<td><code>std::function&lt;void(const HttpResponsePtr&amp;)&gt;</code></td>
</tr>
<tr>
<td>智能指针</td>
<td><code>HttpRequestPtr</code>, <code>HttpResponsePtr</code></td>
</tr>
<tr>
<td><code>const</code> 成员函数</td>
<td><code>void getPic(...) const</code></td>
</tr>
<tr>
<td>C++调用C接口</td>
<td><code>stat(path.c_str(), &amp;buffer)</code></td>
</tr>
</tbody>
</table>
<p dir="auto">​</p>
]]></description><link>http://forum.d2learn.org/topic/164/在linux环境下创建c-drogon-项目-进行接口测试-项目推动型学习</link><guid isPermaLink="true">http://forum.d2learn.org/topic/164/在linux环境下创建c-drogon-项目-进行接口测试-项目推动型学习</guid><dc:creator><![CDATA[abbkirito]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[关于c++17结构化绑定的一些问题 - auto&amp; [u_2, v_2] 结构化绑定, 为什么decltype(u_2)结果是int而不是int&amp;呢]]></title><description><![CDATA[<p dir="auto">这里decltype 对结构化绑定的别名有个特殊处理 返回的 <strong>引用类型</strong> 是结构化绑定中特殊定义的, 不是传统认为的 引用类型, 指的是成员的声明类型, 除非成员是 T &amp; 才会返回 T &amp;</p>
<p dir="auto">image.png</p>

https://en.cppreference.com/w/cpp/language/decltype.html

<p dir="auto">image.png</p>

https://en.cppreference.com/w/cpp/language/structured_binding.html

]]></description><link>http://forum.d2learn.org/topic/136/关于c-17结构化绑定的一些问题-auto-u_2-v_2-结构化绑定-为什么decltype-u_2-结果是int而不是int-呢</link><guid isPermaLink="true">http://forum.d2learn.org/topic/136/关于c-17结构化绑定的一些问题-auto-u_2-v_2-结构化绑定-为什么decltype-u_2-结果是int而不是int-呢</guid><dc:creator><![CDATA[SPeak]]></dc:creator><pubDate>Invalid Date</pubDate></item></channel></rss>