4

次のような構造体の const 配列があります。

static const SettingsSuT _table[] = {{5,1}、{1,2}、{1,1}など};

構造は次のとおりです。

  • size_bytes:
  • アイテム数:
  • その他の「メタデータ」メンバー

したがって、「合計サイズ」は、1 つの要素の size_bytes*num_items です。この情報はすべて const 配列にあり、コンパイル時に利用できます。ただし、_table の合計サイズは EEPROM 自体のサイズとは関係がないことに注意してください。_table は EEPROM をミラーリングしません。必要なレイアウト、使用法、およびその他の「メタデータ」タイプの情報のみを記述します。ただし、このメタデータを使用して、使用している EEPROM の量を判断できます。

配列は、固定/最大サイズを持つ外部 EEPROM に格納されているデータを単に記述します。機能が追加および削除されると、const 配列のエントリが変更されます。現在、データの合計サイズをランタイム チェックして、EEPROM サイズを超えないようにしています。

ただし、ビルドがすぐに停止するように、これらのランタイム チェックの多くを static_assert スタイルのテンプレート チェックに変更しています。私はテンプレートの専門家ではないので、これについていくつかの助けを借りることができます.

したがって、質問: すべての要素のサイズを合計するテンプレートを作成し (各要素の値を乗算してから、すべての結果を追加する)、 static_assert を実行し、マジック ナンバーのサイズを超えた場合にビルドを停止する方法EEPROMの。ひとつのアプローチとして典型的な再帰階乗テンプレートの例を見ていましたが、配列にアクセスできず、const値が必要です(と​​思います)。

助けてくれてどうもありがとう、

4

4 に答える 4

0

これは基本的にlitbと同じ答えですが、配列サイズをハードコーディングせずにサイズを追加する方法も示しています。それがとても複雑に見える理由です。

どの部分で助けが必要かは明確ではありません。以下は、メモリ内の配列ではなく、型を使用してすべてのメタデータを追跡する方法です。これにより、構造体のconstintでは実行できない列挙型を使用したコンパイル時のチェックが可能になります。さらにメタデータがある場合は、[設定]のテンプレートにパラメーターを追加し、それらを列挙値として保存します。

Lokiライブラリの使用:http://loki-lib.sourceforge.net/index.php?n=Main.Development。MakeTypeListの実装方法により、18個の「設定」に制限されています。

TypeAt<TList, index>::Result::size_bytesたとえば、を使用してメタデータにアクセスできます。

   #include "loki-0.1.7\include\loki\typelist.h"
   #include "loki-0.1.7\include\loki\static_check.h"

   using namespace Loki;
   using namespace Loki::TL;

   // based on the Length<> template from loki for adding up the sizes
   template <class TList> struct TotalSize;
   template <> struct TotalSize<NullType>
   { enum { value = 0 }; };
   template <class T, class U>
   struct TotalSize< Typelist<T, U> >
   { enum { value = T::size_bytes*T::num_items + TotalSize<U>::value }; };

   // struct for holding the sizes (and other meta data 
   // if you add extra template args and enum values)
   template <size_t s, size_t n> struct Settings
   { enum { size_bytes = s, num_items = n }; };

   // the table of setting structs (limited to 18)
   typedef MakeTypelist< Settings<5,1>, Settings<1,2>, Settings<1,1> >
   SettingsSuT;

   int _tmain(int argc, _TCHAR* argv[])
   {
       LOKI_STATIC_CHECK(TotalSize< SettingsSuT::Result >::value == 8,is8);
       // this will trigger at compile time if uncommented
       //LOKI_STATIC_CHECK(TotalSize< SettingsSuT::Result >::value != 8,isnt8);

       int x = TotalSize< SettingsSuT::Result >::value;
       return 0;
   }
于 2009-02-05T22:56:14.277 に答える
0

私の肘掛け椅子から、コンパイル時にサイズをチェックできるように、構成データを構造体として表現しようとする傾向があります (静的アサートはこれを行うことができます)。提供された情報に基づいて、これが適切なアプローチであるかどうかを言うのは難しいですが、同様に、同じ理由で、それを却下する直接の理由は見当たりません.

テーブルの基本的な翻訳は次のようになります。

struct SettingsTable
{
    char a[5][1];//maybe call it "featureX_conf", or whatever...
    char b[1][2];
    char c[1][1];
};

(適切なコンパイラ マジックを挿入して、パディングとアラインメントを削除しますが、実際charには、ほとんどのプラットフォームとコンパイラの組み合わせでは、この種のことは一般的に影響を受けないようです。)

次に、必要に応じて使用できるサイズを取得sizeofします。実際の値の表がまだ必要な場合は、この方法で生成できます。少し醜いかもしれませんが、簡単にマクロの背後に隠されています。

これがより多くのテンプレートを使用するアプローチよりも「優れている」かどうかは、おそらくターゲット市場によって異なります.

于 2009-02-06T00:19:22.143 に答える