结构大小,检查是64位还是32位

时间:2010-09-21 01:25:36

标签: c#

我有一个Windows应用程序,它执行一个简单的例程来确定是否存在USB令牌。该方法始终在32位计算机上正常工作,但在64位计算机上进行测试时,我们开始看到意外结果。

我正在调用以下方法

[StructLayout(LayoutKind.Sequential)]
internal struct SP_DEVINFO_DATA
{
    public Int32 cbSize;
    public Guid ClassGuid;
    public Int32 DevInst;
    public UIntPtr Reserved;
};

[DllImport("setupapi.dll")] 
internal static extern Int32 SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, Int32 MemberIndex, ref  SP_DEVINFO_DATA DeviceInterfaceData);

SP_DEVINFO_DATA结构的文档告诉我们 cbSize 是 SP_DEVINFO_DATA结构的大小(以字节为单位)。

如果我们为32位计算机计算cbSize,那么对于64位计算机,它将为28和32。

我已经通过使用不同的cbSize值重新编译在两台机器上对此进行了测试,我想知道的是如何将其计算为运行时?我的应用程序需要在两种架构上运行。

internal static Int32 GetDeviceInfoData(Int32 iMemberIndex)
{
    _deviceInfoData = new Win32DeviceMgmt.SP_DEVINFO_DATA
    {
        cbSize = ?? // 28 When 32-Bit, 32 When 64-Bit,
        ClassGuid = Guid.Empty,
        DevInst = 0,
        Reserved = UIntPtr.Zero
    };

    return Win32DeviceMgmt.SetupDiEnumDeviceInfo(_deviceInfoSet, iMemberIndex, ref _deviceInfoData);
}

由于

罗汉

4 个答案:

答案 0 :(得分:9)

使用Marshal.SizeOf:

_deviceInfoData = new Win32DeviceMgmt.SP_DEVINFO_DATA
    {
        cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32DeviceMgmt.SP_DEVINFO_DATA);
        // etc..
    }

答案 1 :(得分:1)

IntPtr的大小在32和64上发生变化 尝试

cbsize = IntPtr.Size == 4 ? 28 : 32

编辑:更正为IntPtr.Size,但我更喜欢汉斯'System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32DeviceMgmt.SP_DEVINFO_DATA);,因为没有神奇的数字。不知道那里有。

答案 2 :(得分:1)

为什么不Environment.Is64BitOperatingSystemEnvironment.Is64BitProcess

答案 3 :(得分:0)

看起来像对齐问题。

尝试设置Pack属性。

修改

我查了一下:http://www.pinvoke.net/default.aspx/Structures/SP_DEVINFO_DATA.html

它说:

  

在32位平台上,所有SetupApi   结构是1字节包装。在64位   SetupApi结构的平台   8字节打包。 IE为32位   对于64位,SP_DEVINFO_DATA.cbSize = 28   SP_DEVINFO_DATA.cbSize =(28 + 4)= 32.SP_DEVINFO_DATA.cbSize =(28 + 4)= 32。