Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different struct attribute based 32bit or 64bit

Tags:

c#

Is there a way I can apply an attribute to a struct conditionally?

If the machine is 32bit I want to apply this attribute

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

If the machine is 64bit I want to apply this attribute

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

Or alternatively could I substitute a value within the attribute...

32bit (Pack = 2)

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

64bit (Pack = 8)

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

I tried using this example but it’s for custom attributes, not existing ones.

Update:

  • I'd like to comile to "Any CPU"
  • The attribute is for the SHFILEOPSTRUCT and depending on the processor uses either or.
  • I don't want to have to compile two versions.
like image 981
Rob Avatar asked Sep 13 '12 16:09

Rob


2 Answers

Good question.

The answer I first thought of was preprocessor directives and 32- and 64-bit compiled assemblies. You can use the same code, even the same project, just build and deploy it two ways depending on the target system:

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

This would require defining Bit32 and Bit64 compilation constants for your project based on the target architecture, and probably building your app twice.

If you want to do this at runtime, I don't think it's possible unless you emit the entire class dynamically at runtime. The attributes may only have constant data, and they cannot be conditionally applied at runtime (preprocessor directives operate at compile-time, not runtime).

The only other way I can think to do this is to copy the class definition into two namespaces, and conditionally use one or the other based on the Environment.Is64BitOperatingSystem property. You can use this property to conditionally control which class you instantiate, or which strategy for creation you choose (which factory method or related pattern is used), but you can't conditionally control attributes at runtime; their information is statically compiled into the assembly manifest as metadata. This one in particular is used by the runtime itself to define how it stores the object's members as heap data, and you don't ever really look for this attribute in user code and use it to define behavior (thus ignoring or specifying a conditional Pack value at runtime).

like image 92
KeithS Avatar answered Oct 06 '22 08:10

KeithS


Create two different build targets (one for 32 bit, one for 64 bit), add a conditional compilation symbol for each (x86 for one, x86_64 for the other) and use #ifdef's around the structure definitions.

like image 37
PhonicUK Avatar answered Oct 06 '22 09:10

PhonicUK