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; 
}

最終的にブロックして値crcを返すようにする方法は?? プリプロセッサ return_value() の書き方 ???

4

1 に答える 1

0

finally ブロックは を適切に削除するitemnameので、その部分について心配する必要はありません。唯一のトリックは、戻り値を -1 にすることはできません (つまり、-1 は正当な戻り値ではありません) end_try。次に、 と同様raise(e)に、マクロにパラメーターを指定できます。

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

非整数型を返すことができる関数を書きたい場合は、このトリックを実行できます: 関数が実際に int を返して成功/失敗を通知し、成功の場合は実際の「戻り値」を渡します (非整数型 1) ポインター パラメーターを介して戻る:

#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 に答える