0

我在项目中使用С语言。最终,我开始注意到大部分代码都是检查。在项目中函数 bool 的返回类型。因为我们正在使用媒体,如果函数读取或写入返回 false 我们必须中断程序,前段时间我了解到在 Visual Studio 中有内置异常(使用 Visual Studio 2008)

__try
__finally

在项目中,我们使用日志。所有函数都使用日志。我们决定将日志和异常结合起来。使用预处理器

#define try             do                                                     \
                        {                                                      \
                        Int32_T __FUNCTION__##ReturnValue = -1;                \
                        LOG_BEGIN();                                           \
                        __try                                                  \
                        {

#define finally         }                                                      \
                        __finally                                              \
                        {

#define end_try         }                                                      \
                        if( __FUNCTION__##ReturnValue != -1 )                  \
                        {                                                      \
                        return LOG_END_WITH(__FUNCTION__##ReturnValue);    \
                        }                                                      \
                        else                                                   \
                        {                                                      \
                        LOG_END();                                         \
                        return;                                            \
                        }                                                      \
                        }while(0)   
#define raise(e)        RaiseException( e, EXCEPTION_NONCONTINUABLE, 0, NULL )

#define return_false    __FUNCTION__##ReturnValue = 0;                         \
                        __leave

#define return_true     ##__FUNCTION__##ReturnValue = 1;                       \
                        __leave

#define return_void     ##__FUNCTION__##ReturnValue = -1;                      \
                        __leave

使用示例。函数返回布尔值

Bool_T Node_Insert( IN OUT Tree_T * tree, IN Text_T fullPath, ... )
{
   Text_T  itemName     = NULL;
   int   * delimiterPos = NULL;

   try
   {
          // if tree is empty we should add ROOT_PATH
          //
      if( Tree_IsEmpty( IN *tree ) )
      {
         if( failed Tree_CreateRoot( IN OUT *tree, IN datafield ) )
         {
            LOG_ERROR( "Node_Insert FAILURE -->  Tree_CreateRoot failed" );
            return_false;
         }
       }

      if( Text_Length( IN fullPath ) > 1 )
      {
        ...
        // Allocate memory for Text
        //
        item = Text_New();

        // Allocate for delimeterPos array
        //
        delimiterPos = NEW(n, sizeof(elem));
        ...

        while( i < nDelimiter )
        {
            ...
            ...
            ...
        }

      }
      else if ( Text_Length( IN fullPath ) == 1  ) 
      {
        // we have already added ROOT
        //
        return_true;

      }else{

       LOG_ERROR( "Node_Insert FAILURE --> Path length is not correct" );
       return_false;
      }
    }

    // In the end we need free allocated memory
    //
    finally
    {
    Text_Delete( IN OUT &itemName );
         free( delimiterPos );
    }
    // in end_try preprocessor we write log and return true or false
    //
    end_try;
}

使用示例。不返回值的方法

void Ifo_ReadBufferHeader( IN Uint8_T * buffer, ... IN OUT Int32_T * position )
{
   Text_T fullPath = NULL;

   try
   {
     // getting buffer size
     //
     Uint32_T size = Buffer_GetSize( IN buffer );

     // getting mode
     //
     Uint8_T writeMode = Buffer_GetWritingMode( IN buffer );

     if( Ifo_IsAddMode( IN static_cast(DataIfoMode_T, writeMode) ) )
     {
         Uint32_T pos = 1 + Ifo_GetLabelLength() + 23;

        // getting path length
        //
        fullPath = Text_New( IN "", IN mp );
        Buffer_GetNameField( IN buffer, OUT &fullPath, IN OUT &pos );

        *parentFolderPath = fullPath;
        *position = pos;
     } else if( Ifo_IsRenameMode( IN static_cast(DataIfoMode_T, writeMode ) ) 
           {
              *position = 1 + Ifo_GetLabelLength() + 23;
           }

         *bufferSize = size;
         *mode       = static_cast(DataIfoMode_T, writeMode);

         // return_void preprocessor that use
         //
         return_void;

    }
    finally
    {
        // After run the main code you must free allocated memory
        //
        Text_Delete( IN OUT &fullPath );
    }
    end_try;
}

我的问题是。我如何设计它将返回一个值?也就是函数会返回一个值,比如计算缓冲区CRC作为一个值返回。我如何通过使用这些宏来做到这一点。

int GetCrcBuffer( IN Uint32_T buffer, IN Tree_T tree )
{
    Text_T itemName = NULL;
    int    crc      = 0;

    try
    {
        ...
        ...
        itemName = Text_New();

        if( crc != 12 )
        {
         return_value(crc); // ???? return value of crc and delete text??? how???
        }
        ...
        ...
    }
    finally
    {
        Text_Delete( IN OUT itemName );
    }
    end_try; 
}

如何让它运行 finally 块并返回值 crc?如何编写预处理器 return_value() ???

4

1 回答 1

0

您的 finally 块将正确删除itemname,因此您不必担心那部分。唯一的技巧是您的返回值不能为 -1(即:-1 不能是合法的返回值),因为这表示end_try. 然后就像 with 一样raise(e),您可以为宏指定一个参数:

#define return_value(v) ##__FUNCTION__##ReturnValue = (v);                       \
                        __leave

如果你想编写一个可以返回非整数类型的函数,你可以这样做:让函数实际返回一个 int,表示成功/失败,在成功的情况下,传递实际的“返回值”(非整数类型一)通过指针参数返回:

#define return_value2(v) *ret_val=(v);                                          \
                         ##__FUNCTION__##ReturnValue = 1;                       \
                         __leave

int GetMyType( IN Uint32_T buffer, IN Tree_T tree, MyType* ret_val )
{
  ...
}

注意:ret_val指向的值只有在函数没有返回 -1 时才有效

于 2012-04-11T10:33:13.427 回答