在Doxygen中引用参数的正确方法是什么?

83

我有一个函数的以下Doxygen文档:

/**
  @brief Does interesting things

  @param[in]  pfirst The first parameter: a barrel full of monkeys

  @pre
    "pfirst" must have been previously passed through BarrelFiller()
*/

注意pfirst是一个参数,并且它在前置条件中被引用。

我在这里用引号括起来是因为我想将其与文本的其余部分区分开。但如果能以这种方式做到Doxygen将突出显示命令并最好将其链接到参数定义,那就更好了。是否有方法可以实现这一点?

最好只使用默认配置(或稍作修改)即可实现此目的。

3个回答

96

Doxygen提供命令\p,用于指示下一个单词是函数的参数。您可以按以下方式使用它:

... the \p x and \p y coordinates are used to ...

我认为默认情况下,这将使用打字机字体来表示。我不认为它目前提供任何自动链接功能,但在未来可能会有。

有一个相关的命令\a,用于标记成员参数。默认情况下,它在文本中以强调形式显示(<em>arg</em>

您可以在Doxygen 特殊命令参考中找到更多信息。


7
我认为这并非OP所问的确切内容(虽然我绝不认为我比他更了解他自己的问题)。他主要想知道如何对文本进行标记,使输出在语义上被标记为参数(例如,在HTML输出中,一个属于“paramname”类的元素),而不仅仅像默认样式表中的参数一样呈现相似。如果你正在改变Doxygen的输出界面,这显然很重要,但目前没有经济实惠的方法来实现它。 - alecov
1
即使您希望输出使用HTML类标识参数,仍需在源代码注释中使用'\p'或'\a'标记来告知Doxygen您的意图。如何在输出中呈现这些标记是另一回事 - 可以使用'<tt>'等方式或作为类。如何让Doxygen执行此操作是另一回事 - 可以查看XML输出。 - simon.watts
10
为了让任何来到这里并尚未在Doxygen文档中注意到这个条款的人都能清楚地理解:您可以将任何命令的前导\替换为@,从而获得相同的结果。因此,@p 在这里也适用。 - underscore_d

10

我知道你在询问@param参数,但谷歌搜索也会将@return类型的问题带到这里,所以这里也提供一下答案:

使用Doxygen #在返回值前创建超链接到其定义:

使用#符号。

完整示例(请查看下面带有#@return类型):

#include <stdarg.h> // for va_list, va_start, va_end
#include <stdio.h>  // for vsnprintf

// Function prototype:

int debug_printf(const char *format, ...) __attribute__((format(printf, 1, 2)));

// Function definition:

/// @brief      Function to print out data through serial UART for debugging.
/// @details    Feel free to add more details here,
///             perhaps
///             even
///             a
///             whole
///             paragraph.
/// @note       Optionally add a note too.
/// @param[in]  format  `printf`-like format string
/// @param[in]  ...     `printf`-like variadic list of arguments corresponding 
///                 to the format string
/// @return     Number of characters printed if OK, or < 0 if error:
///             - #DEBUG_ERR_ENCODING
///             - #DEBUG_ERR_OVERFLOW
///             - #DEBUG_ERR_UART
int debug_printf(const char *format, ...)
{
    int num_chars_printed;

    va_list args;
    va_start(args, format);

    // Use `vsnprintf()` now here to format everything into a single string
    // buffer, then send out over the UART
    // - num_chars_printed could be set to one of the error codes listed above
    //   here

    va_end(args);

    return num_chars_printed;
}

现在,Doxygen的输出将错误返回类型显示为子项目列表,位于行Number of characters printed if OK, or < 0 if error:下,每个错误类型因其前面的#字符而转化为其各自定义的URL。

Doxygen参考:

  1. 请查看@Jeremy Sarao的答案和我们脑海中的部落知识。
  2. 部落知识。我不知道如何在Doxygen文档中找到这些信息。
  3. 在此处查看Doxygen的所有特殊命令的列表:http://www.doxygen.nl/manual/commands.html(例如:\brief@brief\note@note\details@details\example等)。
  4. 请注意,可能的param值为param[in]param[in,out]param[out]。更多细节和官方文档请参见以下引用:
    1. 那是一个输入还是输入/输出参数?Doxygen,C++
    2. param特殊命令的官方Doxygen文档:http://www.doxygen.nl/manual/commands.html#cmdparam
  5. 其他演示Doxygen使用的代码示例:
    1. STM32如何获取最后一个复位状态
    2. C代码中的错误处理

其他参考:

  1. GCC的printf格式属性文档:
    1. https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html - 参见“format”部分
    2. 如何在用户定义的函数中使用格式化字符串?
    3. 如何在C++类方法中正确使用__attribute__((format(printf, x, y)))?
  2. printf基本包装器实现:https://github.com/adafruit/ArduinoCore-samd/blob/master/cores/arduino/Print.cpp#L189

其他Doxygen示例:

(从我的eRCaGuy_dotfiles项目中复制而来

完整的Doxygen函数头示例:

/// \brief          A brief one or two line description of the function.
/// \note           An important note the user should be aware of--perhaps many 
///                 lines.
/// \details        Extra details.
///                 Perhaps
///                 even
///                 a long
///                 paragraph.
/// \param[in]      var1            Description of variable one, an input
/// \param[in]      var2            Description of variable two, an input
/// \param[out]     var3            Description of variable three, an output 
///                     (usu. via a pointer to a variable)
/// \param[in,out]  var4            Description of variable four, an 
///                     input/output (usu. via a pointer) since its initial 
///                     value is read and used, but then it is also updated by 
///                     the function at some point
/// \return         Description of return types. It may be an enum, with these
///                 possible values:
///                 - #ENUM_VALUE_1
///                 - #ENUM_VALUE_2
///                 - #ENUM_VALUE_3
my_enum_t myFunc(int var1, int var2, int* var3, int* var4)
{
    // function implementation here
    
    my_enum_t error = ENUM_VALUE_1;
    
    // Check for NULL pointers
    if (!var3 || !var4)
    {
        // var3 or var4 are NULL pointers, which means they can't be
        // dereferenced
        error = ENUM_VALUE_2;
        goto done;
    }

    if (something_else)
    {
        error = ENUM_VALUE_3;
        goto done;
    }

done:
    return error;
}

您也可以使用@代替\
/// @brief          A brief one or two line description of the function.
/// @param[in]      var1            Description of variable one, an input
/// @param[in]      var2            Description of variable two, an input
/// @param[out]     var3            Description of variable three, an output 
///                     (usu. via a pointer to a variable)
/// @param[in,out]  var4            Description of variable four, an 
///                     input/output (usu. via a pointer) since its initial 
///                     value is read and used, but then it is also updated by 
///                     the function at some point
/// @return         None
void myFunc(int var1, int var2, int* var3, int* var4)
{
    // function implementation here
}

这里是较短的版本,现在又回到了使用\而不是@的方式:

/// \brief          A brief one or two line description of the function.
/// \param[in]      var1            Description of variable one, an input
/// \param[in]      var2            Description of variable two, an input
/// \param[out]     var3            Description of variable three, an output (
///                     usu. via a pointer to a variable)
/// \param[in,out]  var4            Description of variable four, an 
///                     input/output (usu. via a pointer) since its initial 
///                     value is read and used, but then it is also updated by 
///                     the function at some point
/// \return         None
void myFunc(int var1, int var2, int* var3, int* var4)
{
    // function implementation here
}

我发现你很好地缩进了所有的内容,这在美学上非常令人愉悦,但是手动维护它真的很痛苦。你知道有没有任何Doxygen自动格式化工具可以帮助解决这个问题吗? - 303
@303,我不这样做。对于普通的注释块,我可以通过按下Alt + Q在Sublime Text中将注释块硬换行到我的第一列宽度“标尺”设置。然而,对于Doxygen注释,我的方法是简单地转到我的笔记文件并手动从那里复制粘贴一个Doxygen头到我的代码中,然后手动更新它。我经常这样做。我保持这个笔记文档打开,并在需要时从中复制粘贴一个新的Doxygen头。 - Gabriel Staples
@303,更新:Eclipse是我与Sublime Text 4一起使用的主要IDE之一,它具有一个功能,即如果您在带有3个Doxygen斜杠的行上按Return键,则会自动将3个斜杠添加到新行中以供Doxygen使用。这很方便,可以节省一点时间和工作量。然后,只需几个制表符,我就可以继续以所需的缩进级别进行输入。 - Gabriel Staples

0

在要引用的参数前面使用"#"符号:

#pfirst must have been previously passed through BarrelFiller()

(在Doxygen手册中)


6
# 用于指代成员变量,而不是函数参数。 - xuhdev
5
错误答案。如果pfirst是一个参数,这会产生一个“警告:无法解析对pfirst的显式链接请求”,并且哈希将按字面意义写入生成的文档中。如果pfirst是成员函数或变量,则输出是一个漂亮的链接。 - Stein
+1 是因为在 @return 类型(值)前面使用 # 符号可以创建到每个返回值定义的链接,这正是我想知道的。例如:/// @return 打印的字符数,如果出错则为 <0:#OVERFLOW 或 #UART。现在,在我的生成的 Doxygen 中,“OVERFLOW”和“UART”显示为超链接到它们各自的定义,这非常好。 - Gabriel Staples
我决定将其编写为答案,因为尽管它不完全是对OP问题的答案,但它与之相关,并且返回类型的谷歌搜索也会导致此处:https://dev59.com/WWUp5IYBdhLWcg3wRF6c#56745246 - Gabriel Staples

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接