Windows Api : GetSystemInfo与GetNativeSystemInfo的区别

   MSDN中介绍,GetSystemInfo被用来获取当前系统的相关信息,但是笔者在使用中出现了问题。笔者的操作系统是Windows 7 64位,在win32工程中调用此函数,发现得到的cpu架构居然是x86,显然不对。经过查找资料,笔者发现有网友也遇到了相同的问题并建议调用GetNativeSystemInfo,结果果然正确。现在将此问题记录下来分享给大家。因为真正的强人不是技术有多强,而是能和其他人分享成果共同进步。
       下面具体分析下。MSDN对GetNativeSystemInfo是这样解释的:该api是获取当前的系统信息给运行在WOW64下的一个应用程序。如果在一个64位的应用中调用此函数,那它等效于GetSystemInfo.
       言外之意,如果一个32位的应用运行在64位操作系统上这两个api是不同的。再来看一下什么是WOW64:MSDN里介绍道WOW64是一个32位的模拟器,它的主要作用就是让一个32位的应用程序无缝地运行在64位操作系统之上。换句话说,就是一个win32的应用要在64位操作系统上正常运行,就要凭借WOW64。
       总结一下,笔者开头的问题本质就是api兼容方面的问题,具体说应用程序和操作系统匹配的情况下没有任何问题,但是32位应用程序按理来说是不能运行在64位操作系统上的,为了兼容微软推出了WOW64来兼容,但是此时GetSystemInfo就可能取到错误的信息了。为了得到正确结果,我们就需要调用更底层的api GetNativeSystemInfo了。

        代码如下 :
       Windows <wbr>Api <wbr>: <wbr>GetSystemInfo与GetNativeSystemInfo的区别

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设我们要封装的 Windows API 是 GetSystemInfo 函数,该函数的定义如下: ```c++ void WINAPI GetSystemInfo( _Out_ LPSYSTEM_INFO lpSystemInfo ); ``` 其中,`LPSYSTEM_INFO` 是一个指向 `SYSTEM_INFO` 结构体的指针。我们需要将这个结构体定义在 C++/CLI 中,并将其作为参数传递给 GetSystemInfo 函数。 下面是一个示例代码: ```c++ #include <Windows.h> namespace MyNamespace { public ref class MyApiWrapper { public: static void GetSystemInfo([Out] System::IntPtr% systemInfoPtr) { SYSTEM_INFO nativeInfo; ::GetSystemInfo(&nativeInfo); systemInfoPtr = System::IntPtr(&nativeInfo); } }; } ``` 在这个示例代码中,我们定义了一个名为 `MyApiWrapper` 的 C++/CLI 类,其中包含一个名为 `GetSystemInfo` 的静态方法。该方法使用 `[Out]` 特性标记 `systemInfoPtr` 参数,以指示该参数是一个输出参数。 在方法内部,我们声明了一个 `SYSTEM_INFO` 结构体的变量 `nativeInfo`,然后调用 `::GetSystemInfo` 函数,将该结构体的指针传递给它。函数调用完成后,我们将 `nativeInfo` 的地址赋值给 `systemInfoPtr` 参数。 接下来,我们可以在 VB.NET 中调用这个封装后的 API,如下所示: ```vb.net Imports System.Runtime.InteropServices Imports MyNamespace Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim systemInfoPtr As IntPtr MyApiWrapper.GetSystemInfo(systemInfoPtr) Dim systemInfo As SYSTEM_INFO = Marshal.PtrToStructure(systemInfoPtr, GetType(SYSTEM_INFO)) MessageBox.Show(systemInfo.dwNumberOfProcessors.ToString()) End Sub <StructLayout(LayoutKind.Sequential)> Private Structure SYSTEM_INFO Public wProcessorArchitecture As UShort Public wReserved As UShort Public dwPageSize As UInteger Public lpMinimumApplicationAddress As IntPtr Public lpMaximumApplicationAddress As IntPtr Public dwActiveProcessorMask As IntPtr Public dwNumberOfProcessors As UInteger Public dwProcessorType As UInteger Public dwAllocationGranularity As UInteger Public wProcessorLevel As UShort Public wProcessorRevision As UShort End Structure End Class ``` 在这个 VB.NET 代码中,我们导入了 `System.Runtime.InteropServices` 命名空间,以便使用 `Marshal.PtrToStructure` 函数。然后,我们创建一个 `MyApiWrapper` 对象,并调用其 `GetSystemInfo` 方法,将输出参数 `systemInfoPtr` 传递给它。 接下来,我们使用 `Marshal.PtrToStructure` 函数将 `systemInfoPtr` 转换为 `SYSTEM_INFO` 结构体类型,并获取其中的 `dwNumberOfProcessors` 字段值,最后将其显示在一个消息框中。 需要注意的是,由于 C++/CLI 类库编译为托管代码,因此需要将其与 VB.NET 项目一起编译为 x86 或 AnyCPU 架构,以便在 64 位操作系统上正常运行。如果要在 64 位操作系统上运行,可以编译为 x64 架构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值