我可以在运行时设置StructLayout的size属性吗?

时间:2010-08-17 18:53:58

标签: c#

我尝试使用SendInput在我的应用程序中模拟键盘按下,并希望同时支持32位和64位。

我已经确定为了这个工作,我需要有2个不同的INPUT结构

        [StructLayout(LayoutKind.Sequential)]
    public struct KEYBDINPUT
    {
        public ushort wVk; // Virtual Key Code
        public ushort wScan; // Scan Code
        public uint dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }

    [StructLayout(LayoutKind.Explicit, Size = 28)]
    public struct INPUT32
    {
        [FieldOffset(0)]
        public uint type; // eg. INPUT_KEYBOARD
        [FieldOffset(4)]
        public KEYBDINPUT ki;
    }

    [StructLayout(LayoutKind.Explicit, Size = 40)]
    public struct INPUT64
    {
        [FieldOffset(0)]
        public uint type; // eg. INPUT_KEYBOARD
        [FieldOffset(8)]
        public KEYBDINPUT ki;
    }

我想知道是否有办法在运行时设置StructLayout大小和FieldOffsets,这样我就可以只使用一个INPUT结构并确定大小和字段偏移,具体取决于机。

我已经尝试过下面的代码,但我想知道在运行时是否可以使用相同的代码而不是编译时间。

#if _M_IX86
    [StructLayout(LayoutKind.Explicit, Size = 28)]
#else
    [StructLayout(LayoutKind.Explicit, Size = 40)]
#endif
    public struct INPUT
    {
        [FieldOffset(0)]
        public uint type; // eg. INPUT_KEYBOARD
#if _M_IX86
        [FieldOffset(4)]
#else
        [FieldOffset(8)]
#endif
        public KEYBDINPUT ki;
    }

2 个答案:

答案 0 :(得分:3)

不幸的是,没有。

属性在编译时与类型“融合”,这就是传递给属性构造函数的所有值必须是常量的原因。

在运行时,您无法修改附加到该类型的属性。您可以获取副本并修改其值,但附加到该类型的实际属性将保持不变,因此您不能“欺骗”mscorlib代码来查看您的更改而不是原始更改。

答案 1 :(得分:1)

您可以始终拥有2个结构,并确定在运行时使用哪个结构。

通过适当的设计,您可以将代码重复限制为几行。 (加上结构两次。)