7

属性を構造体に条件付きで適用する方法はありますか?

マシンが32bitの場合、この属性を適用したい

[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]

マシンが64bitの場合、この属性を適用したい

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

または、属性内の値を代用できますか...

32bit (パック=2)

[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]

64bit (パック=8)

[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)]

このを使用してみましたが、既存の属性ではなくカスタム属性用です。

アップデート:

  • 「Any CPU」に賛同したい
  • この属性はSHFILEOPSTRUCT用であり、プロセッサに応じて、またはいずれかを使用します。
  • 2 つのバージョンをコンパイルする必要はありません。
4

3 に答える 3

6

良い質問。

私が最初に考えた答えは、プリプロセッサ ディレクティブと 32 ビットおよび 64 ビットのコンパイル済みアセンブリでした。ターゲット システムに応じて、2 つの方法でビルドしてデプロイするだけで、同じプロジェクトでも同じコードを使用できます。

#ifdef Bit32
[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]
#endif
#ifdef Bit64
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)]
#endif

これには、ターゲット アーキテクチャに基づいてプロジェクトの Bit32 および Bit64 コンパイル定数を定義する必要があり、おそらくアプリを 2 回ビルドする必要があります。

実行時にこれを行いたい場合は、実行時にクラス全体を動的に発行しない限り、それは不可能だと思います。属性は定数データのみを持つことができ、実行時に条件付きで適用することはできません (プリプロセッサ ディレクティブは実行時ではなくコンパイル時に動作します)。

これを実行する唯一の方法は、クラス定義を 2 つの名前空間にコピーし、Environment.Is64BitOperatingSystem プロパティに基づいて条件付きでどちらか一方を使用することです。このプロパティを使用して、どのクラスをインスタンス化するか、またはどの作成戦略を選択するか (どのファクトリ メソッドまたは関連パターンを使用するか) を条件付きで制御できますが、実行時に属性を条件付きで制御することはできません。それらの情報は、メタデータとしてアセンブリ マニフェストに静的にコンパイルされます。特にこれは、オブジェクトのメンバーをヒープ データとして格納する方法を定義するためにランタイム自体によって使用されます。ユーザー コードでこの属性を実際に探したり、それを使用して動作を定義したりすることはありません (したがって、条件付きパックを無視または指定します)。実行時の値)。

于 2012-09-13T16:26:26.770 に答える
1

2 つの異なるビルド ターゲット (1 つは 32 ビット用、もう 1 つは 64 ビット用) を作成し、それぞれに条件付きコンパイル シンボルを追加し (1 つは x86、もう 1 つは x86_64) #ifdef、構造定義の前後に 's を使用します。

于 2012-09-13T16:26:56.543 に答える
0

私はあなたがそれをすることができないと思います。2つの構造体があり、両方を共有構造体またはクラスに変換して処理する方法を提供します...

注:要求している機能は非常に奇妙です(実行時に発生したJITのタイプに基づいて構造の明示的なレイアウトが異なります)。ほとんどの場合、これは、アプリケーションのビット数に関係なく、よく知られている固定プロトコルに一致するバイトの物理レイアウトに使用されます。あなたのケースは、x86 / x64のケースに対して2つの異なるプロトコル/相互運用機能を持っていると見なし、2つの構造に満足することができます。

于 2012-09-13T16:23:39.083 に答える