简体   繁体   English

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

[英]Struct Size, check if 64-bit or 32-bit

I have an windows application that performs a simple routine to determine whether a USB token is present. 我有一个Windows应用程序执行一个简单的例程来确定是否存在USB令牌。 The method has always worked correctly on 32-bit machines however during testing on a 64-bit machine we started to see unexpected results. 该方法始终在32位计算机上正常工作,但在64位计算机上进行测试时,我们开始看到意外结果。

I am calling the following method 我打电话给以下方法

[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);

The documentation for the SP_DEVINFO_DATA structure tells us that the cbSize is the size, in bytes, of the SP_DEVINFO_DATA structure. SP_DEVINFO_DATA结构的文档告诉我们cbSizeSP_DEVINFO_DATA结构的大小(以字节为单位)。

If we calculate cbSize for a 32-bit machine it will be 28 and 32 for a 64-bit machine. 如果我们计算32位机器的cbSize,那么对于64位机器,它将是28和32。

I have tested this on both machines by recompiling with different cbSize values, what i want to know is how can i calculate this as runtime? 我已经通过使用不同的cbSize值重新编译在两台机器上测试了这个,我想知道的是我如何计算它作为运行时? My application need to run on both architectures. 我的应用程序需要在两种架构上运行。

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);
}

Thanks 谢谢

Rohan 罗汉

Use Marshal.SizeOf: 使用Marshal.SizeOf:

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

The size of IntPtr changes on 32 and 64 Try IntPtr的大小在32和64上更改

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

EDIT: Corrected to be IntPtr.Size, but I like Hans' System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32DeviceMgmt.SP_DEVINFO_DATA); better as there are no magic numbers. Didn't know that was there. 编辑:更正为IntPtr.Size,但我喜欢Hans的System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32DeviceMgmt.SP_DEVINFO_DATA);更好,因为没有神奇的数字。不知道那是在那里。

为什么不Environment.Is64BitOperatingSystemEnvironment.Is64BitProcess

Looks like an alignment problem. 看起来像对齐问题。

Try setting the Pack property. 尝试设置Pack属性。

edit 编辑

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

It says: 它说:

On 32bit platforms, all SetupApi structures are 1-Byte packed. 在32位平台上,所有SetupApi结构都是1字节打包。 On 64bit platforms the SetupApi structures are 8-byte packed. 在64位平台上,SetupApi结构是8字节打包的。 IE for 32 bit SP_DEVINFO_DATA.cbSize=28, for 64Bit SP_DEVINFO_DATA.cbSize=(28+4)=32.SP_DEVINFO_DATA.cbSize=(28+4)=32. IE为32位SP_DEVINFO_DATA.cbSize = 28,对于64位SP_DEVINFO_DATA.cbSize =(28 + 4)= 32.SP_DEVINFO_DATA.cbSize =(28 + 4)= 32。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM