У меня есть простая утилита, которая использует небезопасный код для получения информации о версии файла. Когда я скомпилировал это как смешанную платформу (vs2008 / .net 3.5) и развернул на 64-битной машине, я получил ошибку повреждения кучи. Если я перекомпилирую как x86 то все работает ....
Это было удивительно из-за моего понимания .NET Common Type System. Мой небезопасный код использует указатель на короткий и указатель на байт. Разве эти распространенные типы одинакового размера на любой платформе из-за 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;
}
}
Спасибо
Убийца всех зомби и ожидание зомби-апокалипсиса .......
-Джонатан