簡體   English   中英

除非為 x86 平台構建,否則不安全的 c# 代碼會導致 64 位平台上的堆損壞

[英]unsafe c# code causes heap corruption on 64 bit platform unless built for x86 platform

我有一個簡單的實用程序,它使用一些不安全的代碼來獲取文件版本信息。 當我將其編譯為混合平台(vs2008/.net 3.5)並部署到 64 位機器時,出現堆損壞錯誤。 如果我重新編譯為 x86,那么一切正常....

這是令人驚訝的,因為我對 .NET 通用類型系統的理解。 我的不安全代碼使用指向 short 的指針和指向字節的指針。 由於 CTS,這些常見類型在任何平台上都具有相同的大小嗎? 我在這里錯過了什么

using System;
using System.Reflection;
using System.Runtime.InteropServices;


public class Win32Imports
{
    [DllImport("version.dll")]
    public static extern bool GetFileVersionInfo(string sFileName,
          int handle, int size, byte[] infoBuffer);

    [DllImport("version.dll")]
    public static extern int GetFileVersionInfoSize(string sFileName,
          out int handle);

    // The third parameter - "out string pValue" - is automatically
    // marshaled from ANSI to Unicode:
    [DllImport("version.dll")]
    unsafe public static extern bool VerQueryValue(byte[] pBlock,
          string pSubBlock, out string pValue, out uint len);

    // This VerQueryValue overload is marked with 'unsafe' because 
    // it uses a short*:
    [DllImport("version.dll")]
    unsafe public static extern bool VerQueryValue(byte[] pBlock,
          string pSubBlock, out short* pValue, out uint len);
}

public class FileInformation
{
    // Main is marked with 'unsafe' because it uses pointers:
    unsafe public static string GetVersionInformation(string path)
    {

        // Figure out how much version info there is:
        int handle = 0;
        int size =
              Win32Imports.GetFileVersionInfoSize(path,
              out handle);
        if (size == 0) return "";

        byte[] buffer = new byte[size];
        if (!Win32Imports.GetFileVersionInfo(path, handle, size, buffer)) return "";

        // Get the locale info from the version info:
        short* subBlock = null;
        uint len = 0;           
        if (!Win32Imports.VerQueryValue(buffer, @"\VarFileInfo\Translation", out subBlock, out len)) return "";


        // Get the ProductVersion value for this program:
        string spv = @"\StringFileInfo\" + subBlock[0].ToString("X4") + subBlock[1].ToString("X4") + @"\ProductVersion";
        byte* pVersion = null;
        string versionInfo;
        if (!Win32Imports.VerQueryValue(buffer, spv, out versionInfo, out len)) return "";
        return versionInfo;

    }
}

感謝所有僵屍的殺手和等待僵屍啟示錄....... -喬納森

有什么理由不能為此使用FileVersionInfo托管類嗎? 我懷疑它在 32 位和 64 位平台上都能正常工作。

也許因為平台中的指針是 64 位的,但是您使用的是不安全的,所以沒有正確轉換? 還請展示您的 p/invoke 導入的樣子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM