Browse Source

Some marshaling code moved to wrappers, optimized getting of unmanaged strings

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.0@1165 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 20 years ago
parent
commit
e5065b0a9e
  1. 5
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
  2. 13
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Modules/Module.cs
  3. 71
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PrimitiveValue.cs
  4. 66
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugGenericValue.cs
  5. 21
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugModule.cs
  6. 21
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugStringValue.cs
  7. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorSym/ISymUnmanagedDocument.cs
  8. 207
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MetaData.cs
  9. 36
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/Util.cs

5
src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj

@ -363,6 +363,9 @@ @@ -363,6 +363,9 @@
<Compile Include="Src\Wrappers\CorSym\ISymUnmanagedScope.cs" />
<Compile Include="Src\Wrappers\CorSym\ISymUnmanagedVariable.cs" />
<Compile Include="Src\Wrappers\CorSym\SequencePoint.cs" />
<Compile Include="Src\Wrappers\CorDebug\ICorDebugModule.cs" />
<Compile Include="Src\Wrappers\CorDebug\ICorDebugStringValue.cs" />
<Compile Include="Src\Wrappers\CorDebug\ICorDebugGenericValue.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="README.TXT" />
@ -375,4 +378,4 @@ @@ -375,4 +378,4 @@
<Folder Include="Src\Wrappers\MetaData" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
</Project>
</Project>

13
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Modules/Module.cs

@ -127,18 +127,7 @@ namespace Debugger @@ -127,18 +127,7 @@ namespace Debugger
metaData = new MetaData(pModule);
uint pStringLenght = 0; // Terminating character included in pStringLenght
IntPtr pString = IntPtr.Zero;
pModule.GetName(pStringLenght,
out pStringLenght, // real string lenght
pString);
// Allocate string buffer
pString = Marshal.AllocHGlobal((int)pStringLenght * 2);
pModule.GetName(pStringLenght,
out pStringLenght, // real string lenght
pString);
fullPath = Marshal.PtrToStringUni(pString);
Marshal.FreeHGlobal(pString);
fullPath = pModule.Name;
symReader = metaData.GetSymReader(fullPath, null);

71
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PrimitiveValue.cs

@ -25,55 +25,12 @@ namespace Debugger @@ -25,55 +25,12 @@ namespace Debugger
}
}
public unsafe object Primitive {
public object Primitive {
get {
if (CorType == CorElementType.STRING) {
uint pStringLenght = 1; // Terminating character NOT included in pStringLenght
IntPtr pString = Marshal.AllocHGlobal(2);
// For some reason this function does not accept IntPtr.Zero
(corValue.CastTo<ICorDebugStringValue>()).GetString(pStringLenght,
out pStringLenght,
pString);
// Re-allocate string buffer
Marshal.FreeHGlobal(pString);
// Termination null is not included in pStringLenght
pStringLenght++;
pString = Marshal.AllocHGlobal((int)pStringLenght * 2);
(corValue.CastTo<ICorDebugStringValue>()).GetString(pStringLenght,
out pStringLenght,
pString);
string text = Marshal.PtrToStringUni(pString);
Marshal.FreeHGlobal(pString);
return text;
return (corValue.CastTo<ICorDebugStringValue>()).String;
} else {
object retValue;
IntPtr pValue = Marshal.AllocHGlobal(8);
(corValue.CastTo<ICorDebugGenericValue>()).GetValue(pValue);
switch(CorType)
{
case CorElementType.BOOLEAN: retValue = *((System.Boolean*)pValue); break;
case CorElementType.CHAR: retValue = *((System.Char*)pValue); break;
case CorElementType.I1: retValue = *((System.SByte*)pValue); break;
case CorElementType.U1: retValue = *((System.Byte*)pValue); break;
case CorElementType.I2: retValue = *((System.Int16*)pValue); break;
case CorElementType.U2: retValue = *((System.UInt16*)pValue); break;
case CorElementType.I4: retValue = *((System.Int32*)pValue); break;
case CorElementType.U4: retValue = *((System.UInt32*)pValue); break;
case CorElementType.I8: retValue = *((System.Int64*)pValue); break;
case CorElementType.U8: retValue = *((System.UInt64*)pValue); break;
case CorElementType.R4: retValue = *((System.Single*)pValue); break;
case CorElementType.R8: retValue = *((System.Double*)pValue); break;
case CorElementType.I: retValue = *((int*)pValue); break;
case CorElementType.U: retValue = *((uint*)pValue); break;
default: retValue = null; break;
}
Marshal.FreeHGlobal(pValue);
return retValue;
return (corValue.CastTo<ICorDebugGenericValue>()).Value;
}
}
set {
@ -88,27 +45,7 @@ namespace Debugger @@ -88,27 +45,7 @@ namespace Debugger
if (CorType == CorElementType.STRING) {
throw new NotSupportedException();
} else {
IntPtr pValue = Marshal.AllocHGlobal(8);
switch(CorType)
{
case CorElementType.BOOLEAN: *((System.Boolean*)pValue) = (System.Boolean)newValue; break;
case CorElementType.CHAR: *((System.Char*)pValue) = (System.Char)newValue; break;
case CorElementType.I1: *((System.SByte*)pValue) = (System.SByte)newValue; break;
case CorElementType.U1: *((System.Byte*)pValue) = (System.Byte)newValue; break;
case CorElementType.I2: *((System.Int16*)pValue) = (System.Int16)newValue; break;
case CorElementType.U2: *((System.UInt16*)pValue) = (System.UInt16)newValue; break;
case CorElementType.I4: *((System.Int32*)pValue) = (System.Int32)newValue; break;
case CorElementType.U4: *((System.UInt32*)pValue) = (System.UInt32)newValue; break;
case CorElementType.I8: *((System.Int64*)pValue) = (System.Int64)newValue; break;
case CorElementType.U8: *((System.UInt64*)pValue) = (System.UInt64)newValue; break;
case CorElementType.R4: *((System.Single*)pValue) = (System.Single)newValue; break;
case CorElementType.R8: *((System.Double*)pValue) = (System.Double)newValue; break;
case CorElementType.I: *((int*)pValue) = (int)newValue; break;
case CorElementType.U: *((uint*)pValue) = (uint)newValue; break;
default: throw new NotSupportedException();
}
(corValue.CastTo<ICorDebugGenericValue>()).SetValue(pValue);
Marshal.FreeHGlobal(pValue);
(corValue.CastTo<ICorDebugGenericValue>()).Value = newValue;
}
OnValueChanged();
}

66
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugGenericValue.cs

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
namespace Debugger.Wrappers.CorDebug
{
using System;
using System.Runtime.InteropServices;
public partial class ICorDebugGenericValue
{
public unsafe object Value {
get {
object retValue;
IntPtr pValue = Marshal.AllocHGlobal((int)Size);
GetValue(pValue);
switch((CorElementType)Type)
{
case CorElementType.BOOLEAN: retValue = *((System.Boolean*)pValue); break;
case CorElementType.CHAR: retValue = *((System.Char*) pValue); break;
case CorElementType.I1: retValue = *((System.SByte*) pValue); break;
case CorElementType.U1: retValue = *((System.Byte*) pValue); break;
case CorElementType.I2: retValue = *((System.Int16*) pValue); break;
case CorElementType.U2: retValue = *((System.UInt16*) pValue); break;
case CorElementType.I4: retValue = *((System.Int32*) pValue); break;
case CorElementType.U4: retValue = *((System.UInt32*) pValue); break;
case CorElementType.I8: retValue = *((System.Int64*) pValue); break;
case CorElementType.U8: retValue = *((System.UInt64*) pValue); break;
case CorElementType.R4: retValue = *((System.Single*) pValue); break;
case CorElementType.R8: retValue = *((System.Double*) pValue); break;
case CorElementType.I: retValue = *((int*) pValue); break;
case CorElementType.U: retValue = *((uint*) pValue); break;
default: throw new NotSupportedException();
}
Marshal.FreeHGlobal(pValue);
return retValue;
}
set {
IntPtr pValue = Marshal.AllocHGlobal((int)Size);
switch((CorElementType)Type)
{
case CorElementType.BOOLEAN: *((System.Boolean*)pValue) = (System.Boolean)value; break;
case CorElementType.CHAR: *((System.Char*) pValue) = (System.Char) value; break;
case CorElementType.I1: *((System.SByte*) pValue) = (System.SByte) value; break;
case CorElementType.U1: *((System.Byte*) pValue) = (System.Byte) value; break;
case CorElementType.I2: *((System.Int16*) pValue) = (System.Int16) value; break;
case CorElementType.U2: *((System.UInt16*) pValue) = (System.UInt16) value; break;
case CorElementType.I4: *((System.Int32*) pValue) = (System.Int32) value; break;
case CorElementType.U4: *((System.UInt32*) pValue) = (System.UInt32) value; break;
case CorElementType.I8: *((System.Int64*) pValue) = (System.Int64) value; break;
case CorElementType.U8: *((System.UInt64*) pValue) = (System.UInt64) value; break;
case CorElementType.R4: *((System.Single*) pValue) = (System.Single) value; break;
case CorElementType.R8: *((System.Double*) pValue) = (System.Double) value; break;
case CorElementType.I: *((int*) pValue) = (int) value; break;
case CorElementType.U: *((uint*) pValue) = (uint) value; break;
default: throw new NotSupportedException();
}
SetValue(pValue);
Marshal.FreeHGlobal(pValue);
}
}
}
}

21
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugModule.cs

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
namespace Debugger.Wrappers.CorDebug
{
using System;
public partial class ICorDebugModule
{
public string Name {
get {
return Util.GetString(GetName);
}
}
}
}

21
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugStringValue.cs

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
namespace Debugger.Wrappers.CorDebug
{
using System;
public partial class ICorDebugStringValue
{
public string String {
get {
return Util.GetString(GetString);
}
}
}
}

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorSym/ISymUnmanagedDocument.cs

@ -14,7 +14,7 @@ namespace Debugger.Wrappers.CorSym @@ -14,7 +14,7 @@ namespace Debugger.Wrappers.CorSym
{
public string URL {
get {
return Util.GetString(GetURL);
return Util.GetString(GetURL, 0);
}
}
}

207
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MetaData.cs

@ -49,64 +49,33 @@ namespace Debugger.Wrappers.MetaData @@ -49,64 +49,33 @@ namespace Debugger.Wrappers.MetaData
public TypeDefProps GetTypeDefProps(uint typeToken)
{
TypeDefProps typeDefProps;
TypeDefProps typeDefProps = new TypeDefProps();
typeDefProps.Token = typeToken;
uint pStringLenght = 0; // Terminating character included in pStringLenght
IntPtr pString = IntPtr.Zero;
// Get length of string
metaData.GetTypeDefProps(typeDefProps.Token,
pString,
pStringLenght,
out pStringLenght,
out typeDefProps.Flags,
out typeDefProps.SuperClassToken);
// Allocate string buffer
pString = Marshal.AllocHGlobal((int)pStringLenght * 2);
// Get properties
metaData.GetTypeDefProps(typeDefProps.Token,
pString,
pStringLenght,
out pStringLenght,
out typeDefProps.Flags,
out typeDefProps.SuperClassToken);
typeDefProps.Name = Marshal.PtrToStringUni(pString);
Marshal.FreeHGlobal(pString);
typeDefProps.Name =
Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) {
metaData.GetTypeDefProps(typeDefProps.Token,
pString, pStringLenght, out stringLenght, // The string to get
out typeDefProps.Flags,
out typeDefProps.SuperClassToken);
});
return typeDefProps;
}
public TypeRefProps GetTypeRefProps(uint typeToken)
{
TypeRefProps typeRefProps;
TypeRefProps typeRefProps = new TypeRefProps();
typeRefProps.Token = typeToken;
uint unused;
uint pStringLenght = 0; // Terminating character included in pStringLenght
IntPtr pString = IntPtr.Zero;
metaData.GetTypeRefProps(typeRefProps.Token,
out unused,
pString,
pStringLenght,
out pStringLenght); // real string lenght
// Allocate string buffer
pString = Marshal.AllocHGlobal((int)pStringLenght * 2);
metaData.GetTypeRefProps(typeRefProps.Token,
out unused,
pString,
pStringLenght,
out pStringLenght); // real string lenght
typeRefProps.Name = Marshal.PtrToStringUni(pString);
Marshal.FreeHGlobal(pString);
typeRefProps.Name =
Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) {
uint unused;
metaData.GetTypeRefProps(typeRefProps.Token,
out unused,
pString, pStringLenght,out stringLenght // The string to get
);
});
return typeRefProps;
}
@ -128,43 +97,23 @@ namespace Debugger.Wrappers.MetaData @@ -128,43 +97,23 @@ namespace Debugger.Wrappers.MetaData
public FieldProps GetFieldProps(uint fieldToken)
{
FieldProps fieldProps;
FieldProps fieldProps = new FieldProps();
fieldProps.Token = fieldToken;
uint unused;
IntPtr unusedPtr = IntPtr.Zero;
uint pStringLenght = 0; // Terminating character included in pStringLenght
IntPtr pString = IntPtr.Zero;
metaData.GetFieldProps(fieldProps.Token,
out fieldProps.ClassToken,
pString,
pStringLenght,
out pStringLenght, // real string lenght
out fieldProps.Flags,
IntPtr.Zero,
out unused,
out unused,
out unusedPtr,
out unused);
// Allocate string buffer
pString = Marshal.AllocHGlobal((int)pStringLenght * 2);
metaData.GetFieldProps(fieldProps.Token,
out fieldProps.ClassToken,
pString,
pStringLenght,
out pStringLenght, // real string lenght
out fieldProps.Flags,
IntPtr.Zero,
out unused,
out unused,
out unusedPtr,
out unused);
fieldProps.Name = Marshal.PtrToStringUni(pString);
Marshal.FreeHGlobal(pString);
fieldProps.Name =
Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) {
uint unused;
IntPtr unusedPtr = IntPtr.Zero;
metaData.GetFieldProps(fieldProps.Token,
out fieldProps.ClassToken,
pString, pStringLenght, out stringLenght, // The string to get
out fieldProps.Flags,
IntPtr.Zero,
out unused,
out unused,
out unusedPtr,
out unused);
});
return fieldProps;
}
@ -186,45 +135,24 @@ namespace Debugger.Wrappers.MetaData @@ -186,45 +135,24 @@ namespace Debugger.Wrappers.MetaData
public unsafe MethodProps GetMethodProps(uint methodToken)
{
MethodProps methodProps;
MethodProps methodProps = new MethodProps();
methodProps.Token = methodToken;
uint pStringLenght = 0; // Terminating character included in pStringLenght
IntPtr pString = IntPtr.Zero;
//IntPtr pSigBlob;
uint sigBlobSize;
metaData.GetMethodProps(methodProps.Token,
out methodProps.ClassToken,
pString,
pStringLenght,
out pStringLenght, // real string lenght
out methodProps.Flags,
IntPtr.Zero,//new IntPtr(&pSigBlob),
out sigBlobSize,
out methodProps.CodeRVA,
out methodProps.ImplFlags);
// Allocate string buffer
pString = Marshal.AllocHGlobal((int)pStringLenght * 2);
metaData.GetMethodProps(methodProps.Token,
out methodProps.ClassToken,
pString,
pStringLenght,
out pStringLenght, // real string lenght
out methodProps.Flags,
IntPtr.Zero,//new IntPtr(&pSigBlob),
out sigBlobSize,
out methodProps.CodeRVA,
out methodProps.ImplFlags);
methodProps.Name = Marshal.PtrToStringUni(pString);
Marshal.FreeHGlobal(pString);
methodProps.Name =
Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) {
uint sigBlobSize;
metaData.GetMethodProps(methodProps.Token,
out methodProps.ClassToken,
pString, pStringLenght, out stringLenght, // The string to get
out methodProps.Flags,
IntPtr.Zero,//new IntPtr(&pSigBlob),
out sigBlobSize,
out methodProps.CodeRVA,
out methodProps.ImplFlags);
});
methodProps.Signature = null;
//methodProps.Signature = new SignatureStream(pSigBlob, sigBlobSize);
//Marshal.FreeCoTaskMem(pSigBlob);
return methodProps;
@ -239,40 +167,21 @@ namespace Debugger.Wrappers.MetaData @@ -239,40 +167,21 @@ namespace Debugger.Wrappers.MetaData
public ParamProps GetParamProps(uint paramToken)
{
ParamProps paramProps;
ParamProps paramProps = new ParamProps();
paramProps.Token = paramToken;
uint unused;
uint pStringLenght = 0; // Terminating character included in pStringLenght
IntPtr pString = IntPtr.Zero;
metaData.GetParamProps(paramProps.Token,
out paramProps.MethodToken,
out paramProps.ParameterSequence,
pString,
pStringLenght,
out pStringLenght, // real string lenght
out paramProps.Flags,
out unused,
IntPtr.Zero,
out unused);
// Allocate string buffer
pString = Marshal.AllocHGlobal((int)pStringLenght * 2);
metaData.GetParamProps(paramProps.Token,
out paramProps.MethodToken,
out paramProps.ParameterSequence,
pString,
pStringLenght,
out pStringLenght, // real string lenght
out paramProps.Flags,
out unused,
IntPtr.Zero,
out unused);
paramProps.Name = Marshal.PtrToStringUni(pString);
Marshal.FreeHGlobal(pString);
paramProps.Name =
Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) {
uint unused;
metaData.GetParamProps(paramProps.Token,
out paramProps.MethodToken,
out paramProps.ParameterSequence,
pString, pStringLenght, out stringLenght, // The string to get
out paramProps.Flags,
out unused,
IntPtr.Zero,
out unused);
});
return paramProps;
}

36
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/Util.cs

@ -11,22 +11,36 @@ using System.Runtime.InteropServices; @@ -11,22 +11,36 @@ using System.Runtime.InteropServices;
namespace Debugger.Wrappers
{
public delegate void UnmanagedStringGetter(uint bufferSize, out uint returnedSize, System.IntPtr pString);
public delegate void UnmanagedStringGetter(uint pStringLenght, out uint stringLenght, System.IntPtr pString);
public static class Util
{
public static string GetString(UnmanagedStringGetter getter)
{
uint pStringLenght = 0;
IntPtr pString = IntPtr.Zero;
getter(pStringLenght, out pStringLenght, pString);
// Allocate string buffer
pString = Marshal.AllocHGlobal((int)pStringLenght * 2);
getter(pStringLenght, out pStringLenght, pString);
string str = Marshal.PtrToStringUni(pString);
// Release buffer
Marshal.FreeHGlobal(pString);
return str;
return GetString(getter, 64);
}
public static string GetString(UnmanagedStringGetter getter, uint defaultLenght)
{
string managedString;
IntPtr unmanagedString;
uint exactLenght;
// First attempt
unmanagedString = Marshal.AllocHGlobal((int)defaultLenght * 2 + 2); // + 2 for terminating zero
getter(defaultLenght, out exactLenght, defaultLenght > 0 ? unmanagedString : IntPtr.Zero);
if(exactLenght > defaultLenght) {
// Second attempt
Marshal.FreeHGlobal(unmanagedString);
unmanagedString = Marshal.AllocHGlobal((int)exactLenght * 2 + 2); // + 2 for terminating zero
getter(exactLenght, out exactLenght, unmanagedString);
}
// Return managed string and free unmanaged memory
managedString = Marshal.PtrToStringUni(unmanagedString);
Marshal.FreeHGlobal(unmanagedString);
return managedString;
}
}
}

Loading…
Cancel
Save