Browse Source

Replaced some uses of Marshal class with fixed()

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5145 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 16 years ago
parent
commit
8a4cf873a8
  1. 191
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorDebugExtensionMethods.cs
  2. 21
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorSymExtensionMethods.cs
  3. 33
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/Util.cs

191
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorDebugExtensionMethods.cs

@ -13,6 +13,8 @@ namespace Debugger.Interop.CorDebug @@ -13,6 +13,8 @@ namespace Debugger.Interop.CorDebug
{
public static partial class CorDebugExtensionMethods
{
const int EnumerateBufferSize = 16;
static void ProcessOutParameter(object parameter)
{
TrackedComObjects.ProcessOutParameter(parameter);
@ -23,7 +25,7 @@ namespace Debugger.Interop.CorDebug @@ -23,7 +25,7 @@ namespace Debugger.Interop.CorDebug
public static unsafe uint[] GetDimensions(this ICorDebugArrayValue corArray)
{
uint[] dimensions = new uint[corArray.GetRank()];
fixed (void* pDimensions = dimensions)
fixed(uint* pDimensions = dimensions)
corArray.GetDimensions((uint)dimensions.Length, new IntPtr(pDimensions));
return dimensions;
}
@ -31,20 +33,20 @@ namespace Debugger.Interop.CorDebug @@ -31,20 +33,20 @@ namespace Debugger.Interop.CorDebug
public static unsafe uint[] GetBaseIndicies(this ICorDebugArrayValue corArray)
{
uint[] baseIndicies = new uint[corArray.GetRank()];
fixed (void* pBaseIndicies = baseIndicies)
fixed(uint* pBaseIndicies = baseIndicies)
corArray.GetBaseIndicies((uint)baseIndicies.Length, new IntPtr(pBaseIndicies));
return baseIndicies;
}
public static unsafe ICorDebugValue GetElement(this ICorDebugArrayValue corArray, uint[] indices)
{
fixed (void* pIndices = indices)
fixed(uint* pIndices = indices)
return corArray.GetElement((uint)indices.Length, new IntPtr(pIndices));
}
public static unsafe ICorDebugValue GetElement(this ICorDebugArrayValue corArray, int[] indices)
{
fixed (void* pIndices = indices)
fixed(int* pIndices = indices)
return corArray.GetElement((uint)indices.Length, new IntPtr(pIndices));
}
@ -61,133 +63,122 @@ namespace Debugger.Interop.CorDebug @@ -61,133 +63,122 @@ namespace Debugger.Interop.CorDebug
{
if (corCode.IsIL() == 0) return null;
byte[] code = new byte[corCode.GetSize()];
fixed(void* pCode = code)
fixed(byte* pCode = code)
corCode.GetCode(0, (uint)code.Length, (uint)code.Length, new IntPtr(pCode));
return code;
}
// ICorDebugFrameEnum
// ICorDebugEnum
public static IEnumerable<ICorDebugFrame> GetEnumerator(this ICorDebugFrameEnum corFrameEnum)
public static IEnumerable<ICorDebugFrame> GetEnumerator(this ICorDebugFrameEnum corEnum)
{
// TODO: As list
corFrameEnum.Reset();
corEnum.Reset();
while (true) {
ICorDebugFrame corFrame = corFrameEnum.Next();
if (corFrame != null) {
yield return corFrame;
} else {
break;
}
ICorDebugFrame[] corFrames = new ICorDebugFrame[EnumerateBufferSize];
uint fetched = corEnum.Next(EnumerateBufferSize, corFrames);
if (fetched == 0)
yield break;
for(int i = 0; i < fetched; i++)
yield return corFrames[i];
}
}
public static ICorDebugFrame Next(this ICorDebugFrameEnum corFrameEnum)
public static ICorDebugFrame Next(this ICorDebugFrameEnum corEnum)
{
ICorDebugFrame[] corFrames = new ICorDebugFrame[1];
uint framesFetched = corFrameEnum.Next(1, corFrames);
if (framesFetched == 0) {
return null;
} else {
return corFrames[0];
ICorDebugFrame[] corFrames = new ICorDebugFrame[] { null };
uint framesFetched = corEnum.Next(1, corFrames);
return corFrames[0];
}
public static IEnumerable<ICorDebugChain> GetEnumerator(this ICorDebugChainEnum corEnum)
{
corEnum.Reset();
while (true) {
ICorDebugChain[] corChains = new ICorDebugChain[EnumerateBufferSize];
uint fetched = corEnum.Next(EnumerateBufferSize, corChains);
if (fetched == 0)
yield break;
for(int i = 0; i < fetched; i++)
yield return corChains[i];
}
}
public static ICorDebugChain Next(this ICorDebugChainEnum corChainEnum)
{
ICorDebugChain[] corChains = new ICorDebugChain[] { null };
uint chainsFetched = corChainEnum.Next(1, corChains);
return corChains[0];
}
// ICorDebugGenericValue
public static unsafe Byte[] GetRawValue(this ICorDebugGenericValue corGenVal)
{
// TODO: Unset fixing insead
Byte[] retValue = new Byte[(int)corGenVal.GetSize()];
IntPtr pValue = Marshal.AllocHGlobal(retValue.Length);
corGenVal.GetValue(pValue);
Marshal.Copy(pValue, retValue, 0, retValue.Length);
Marshal.FreeHGlobal(pValue);
byte[] retValue = new byte[(int)corGenVal.GetSize()];
fixed(byte* pRetValue = retValue)
corGenVal.GetValue(new IntPtr(pRetValue));
return retValue;
}
public static unsafe void SetRawValue(this ICorDebugGenericValue corGenVal, byte[] value)
{
if (corGenVal.GetSize() != value.Length) throw new ArgumentException("Incorrect length");
IntPtr pValue = Marshal.AllocHGlobal(value.Length);
Marshal.Copy(value, 0, pValue, value.Length);
corGenVal.SetValue(pValue);
Marshal.FreeHGlobal(pValue);
if (corGenVal.GetSize() != value.Length)
throw new ArgumentException("Incorrect length");
fixed(byte* pValue = value)
corGenVal.SetValue(new IntPtr(pValue));
}
public static unsafe object GetValue(this ICorDebugGenericValue corGenVal,Type type)
public static unsafe object GetValue(this ICorDebugGenericValue corGenVal, Type type)
{
object retValue;
IntPtr pValue = Marshal.AllocHGlobal((int)corGenVal.GetSize());
corGenVal.GetValue(pValue);
switch(type.FullName) {
case "System.Boolean": retValue = *((System.Boolean*)pValue); break;
case "System.Char": retValue = *((System.Char*) pValue); break;
case "System.SByte": retValue = *((System.SByte*) pValue); break;
case "System.Byte": retValue = *((System.Byte*) pValue); break;
case "System.Int16": retValue = *((System.Int16*) pValue); break;
case "System.UInt16": retValue = *((System.UInt16*) pValue); break;
case "System.Int32": retValue = *((System.Int32*) pValue); break;
case "System.UInt32": retValue = *((System.UInt32*) pValue); break;
case "System.Int64": retValue = *((System.Int64*) pValue); break;
case "System.UInt64": retValue = *((System.UInt64*) pValue); break;
case "System.Single": retValue = *((System.Single*) pValue); break;
case "System.Double": retValue = *((System.Double*) pValue); break;
case "System.IntPtr": retValue = *((System.IntPtr*) pValue); break;
case "System.UIntPtr": retValue = *((System.UIntPtr*)pValue); break;
default: throw new NotSupportedException();
byte[] value = new byte[(int)corGenVal.GetSize()];
fixed(byte* pValue = value) {
corGenVal.GetValue(new IntPtr(pValue));
switch(type.FullName) {
case "System.Boolean": retValue = *((System.Boolean*)pValue); break;
case "System.Char": retValue = *((System.Char*) pValue); break;
case "System.SByte": retValue = *((System.SByte*) pValue); break;
case "System.Byte": retValue = *((System.Byte*) pValue); break;
case "System.Int16": retValue = *((System.Int16*) pValue); break;
case "System.UInt16": retValue = *((System.UInt16*) pValue); break;
case "System.Int32": retValue = *((System.Int32*) pValue); break;
case "System.UInt32": retValue = *((System.UInt32*) pValue); break;
case "System.Int64": retValue = *((System.Int64*) pValue); break;
case "System.UInt64": retValue = *((System.UInt64*) pValue); break;
case "System.Single": retValue = *((System.Single*) pValue); break;
case "System.Double": retValue = *((System.Double*) pValue); break;
case "System.IntPtr": retValue = *((System.IntPtr*) pValue); break;
case "System.UIntPtr": retValue = *((System.UIntPtr*)pValue); break;
default: throw new NotSupportedException();
}
}
Marshal.FreeHGlobal(pValue);
return retValue;
}
public static unsafe void SetValue(this ICorDebugGenericValue corGenVal, Type type, object value)
{
IntPtr pValue = Marshal.AllocHGlobal((int)corGenVal.GetSize());
switch(type.FullName) {
case "System.Boolean": *((System.Boolean*)pValue) = (System.Boolean)value; break;
case "System.Char": *((System.Char*) pValue) = (System.Char) value; break;
case "System.SByte": *((System.SByte*) pValue) = (System.SByte) value; break;
case "System.Byte": *((System.Byte*) pValue) = (System.Byte) value; break;
case "System.Int16": *((System.Int16*) pValue) = (System.Int16) value; break;
case "System.UInt16": *((System.UInt16*) pValue) = (System.UInt16) value; break;
case "System.Int32": *((System.Int32*) pValue) = (System.Int32) value; break;
case "System.UInt32": *((System.UInt32*) pValue) = (System.UInt32) value; break;
case "System.Int64": *((System.Int64*) pValue) = (System.Int64) value; break;
case "System.UInt64": *((System.UInt64*) pValue) = (System.UInt64) value; break;
case "System.Single": *((System.Single*) pValue) = (System.Single) value; break;
case "System.Double": *((System.Double*) pValue) = (System.Double) value; break;
case "System.IntPtr": *((System.IntPtr*) pValue) = (System.IntPtr) value; break;
case "System.UIntPtr": *((System.UIntPtr*)pValue) = (System.UIntPtr)value; break;
default: throw new NotSupportedException();
}
corGenVal.SetValue(pValue);
Marshal.FreeHGlobal(pValue);
}
// ICorDebugChainEnum
public static IEnumerable<ICorDebugChain> GetEnumerator(this ICorDebugChainEnum corChainEnum)
{
corChainEnum.Reset();
while (true) {
ICorDebugChain corChain = corChainEnum.Next();
if (corChain != null) {
yield return corChain;
} else {
break;
public static unsafe void SetValue(this ICorDebugGenericValue corGenVal, object value)
{
if (value == null)
throw new ArgumentNullException("value");
byte[] val = new byte[(int)corGenVal.GetSize()];
fixed(byte* pValue = val) {
switch(value.GetType().FullName) {
case "System.Boolean": *((System.Boolean*)pValue) = (System.Boolean)value; break;
case "System.Char": *((System.Char*) pValue) = (System.Char) value; break;
case "System.SByte": *((System.SByte*) pValue) = (System.SByte) value; break;
case "System.Byte": *((System.Byte*) pValue) = (System.Byte) value; break;
case "System.Int16": *((System.Int16*) pValue) = (System.Int16) value; break;
case "System.UInt16": *((System.UInt16*) pValue) = (System.UInt16) value; break;
case "System.Int32": *((System.Int32*) pValue) = (System.Int32) value; break;
case "System.UInt32": *((System.UInt32*) pValue) = (System.UInt32) value; break;
case "System.Int64": *((System.Int64*) pValue) = (System.Int64) value; break;
case "System.UInt64": *((System.UInt64*) pValue) = (System.UInt64) value; break;
case "System.Single": *((System.Single*) pValue) = (System.Single) value; break;
case "System.Double": *((System.Double*) pValue) = (System.Double) value; break;
case "System.IntPtr": *((System.IntPtr*) pValue) = (System.IntPtr) value; break;
case "System.UIntPtr": *((System.UIntPtr*)pValue) = (System.UIntPtr)value; break;
default: throw new NotSupportedException();
}
}
}
public static ICorDebugChain Next(this ICorDebugChainEnum corChainEnum)
{
ICorDebugChain[] corChains = new ICorDebugChain[1];
uint chainsFetched = corChainEnum.Next(1, corChains);
if (chainsFetched == 0) {
return null;
} else {
return corChains[0];
corGenVal.SetValue(new IntPtr(pValue));
}
}
@ -209,7 +200,7 @@ namespace Debugger.Interop.CorDebug @@ -209,7 +200,7 @@ namespace Debugger.Interop.CorDebug
public static unsafe void StepRange(this ICorDebugStepper corStepper, bool bStepIn, int[] ranges)
{
fixed (int* pRanges = ranges)
fixed(int* pRanges = ranges)
corStepper.StepRange(bStepIn?1:0, (IntPtr)pRanges, (uint)ranges.Length / 2);
}

21
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorSymExtensionMethods.cs

@ -36,16 +36,19 @@ namespace Debugger.Interop.CorSym @@ -36,16 +36,19 @@ namespace Debugger.Interop.CorSym
return Util.GetString(symDoc.GetURL, 256, true);
}
public static byte[] GetCheckSum(this ISymUnmanagedDocument symDoc)
public static unsafe byte[] GetCheckSum(this ISymUnmanagedDocument symDoc)
{
uint checkSumLength = 0;
symDoc.GetCheckSum(checkSumLength, out checkSumLength, IntPtr.Zero);
IntPtr checkSumPtr = Marshal.AllocHGlobal((int)checkSumLength);
symDoc.GetCheckSum(checkSumLength, out checkSumLength, checkSumPtr);
byte[] checkSumBytes = new byte[checkSumLength];
Marshal.Copy(checkSumPtr, checkSumBytes, 0, (int)checkSumLength);
Marshal.FreeHGlobal(checkSumPtr);
return checkSumBytes;
uint actualLength;
byte[] checkSum = new byte[20];
fixed(byte* pCheckSum = checkSum)
symDoc.GetCheckSum((uint)checkSum.Length, out actualLength, new IntPtr(pCheckSum));
if (actualLength > checkSum.Length) {
checkSum = new byte[actualLength];
fixed(byte* pCheckSum = checkSum)
symDoc.GetCheckSum((uint)checkSum.Length, out actualLength, new IntPtr(pCheckSum));
}
Array.Resize(ref checkSum, (int)actualLength);
return checkSum;
}
// ISymUnmanagedMethod

33
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/Util.cs

@ -21,46 +21,41 @@ namespace Debugger.Interop @@ -21,46 +21,41 @@ namespace Debugger.Interop
return GetString(getter, 64, true);
}
public static string GetString(UnmanagedStringGetter getter, uint defaultLength, bool trim)
public static unsafe string GetString(UnmanagedStringGetter getter, uint defaultLength, bool trim)
{
// 8M characters ought to be enough for everyone...
// (we need some limit to avoid OutOfMemoryExceptions when trying to load extremely large
// strings - see SD2-1470).
const uint MAX_LENGTH = 8 * 1024 * 1024;
string managedString;
IntPtr unmanagedString;
uint exactLength;
if (defaultLength > MAX_LENGTH)
defaultLength = MAX_LENGTH;
// First attempt
unmanagedString = Marshal.AllocHGlobal((int)defaultLength * 2 + 2); // + 2 for terminating zero
try {
getter(defaultLength, out exactLength, defaultLength > 0 ? unmanagedString : IntPtr.Zero);
// TODO: Consider removing "+ 2" for the zero
byte[] buffer = new byte[(int)defaultLength * 2 + 2]; // + 2 for terminating zero
fixed(byte* pBuffer = buffer) {
getter((uint)buffer.Length, out exactLength, defaultLength > 0 ? new IntPtr(pBuffer) : IntPtr.Zero);
exactLength = (exactLength > MAX_LENGTH) ? MAX_LENGTH : exactLength;
if(exactLength > defaultLength) {
// Second attempt
Marshal.FreeHGlobal(unmanagedString);
// TODO: Consider removing "+ 2" for the zero
unmanagedString = Marshal.AllocHGlobal((int)exactLength * 2 + 2); // + 2 for terminating zero
uint unused;
getter(exactLength, out unused, unmanagedString);
byte[] buffer2 = new byte[(int)exactLength * 2 + 2]; // + 2 for terminating zero
fixed(byte* pBuffer2 = buffer2) {
getter((uint)buffer2.Length, out exactLength, new IntPtr(pBuffer2));
managedString = Marshal.PtrToStringUni(new IntPtr(pBuffer2), (int)exactLength);
}
} else {
managedString = Marshal.PtrToStringUni(new IntPtr(pBuffer), (int)exactLength);
}
// TODO: Check how the trimming and the last 0 charater works
// Return managed string and free unmanaged memory
managedString = Marshal.PtrToStringUni(unmanagedString, (int)exactLength);
//Console.WriteLine("Marshaled string from COM: \"" + managedString + "\" lenght=" + managedString.Length + " arrayLenght=" + exactLenght);
// The API might or might not include terminating null at the end
if (trim) {
managedString = managedString.TrimEnd('\0');
}
} finally {
Marshal.FreeHGlobal(unmanagedString);
}
if (trim)
managedString = managedString.TrimEnd('\0');
return managedString;
}
}

Loading…
Cancel
Save