Browse Source

Fixed problem with locking of assembly - the COM method GetReaderForFile was creating new object even though it returned error code

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6249 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
David Srbecký 16 years ago
parent
commit
8381d4b90e
  1. 10
      src/AddIns/Debugger/Debugger.Core/Interop/CorSym.cs
  2. 11
      src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.cs
  3. 16
      src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.generated.cs
  4. 6
      src/AddIns/Debugger/Debugger.Core/Interop/MetaDataWrapper.cs
  5. 22
      src/Tools/ComExtensionMethodGenerator/ComExtensionMethodGenerator.cs

10
src/AddIns/Debugger/Debugger.Core/Interop/CorSym.cs

@ -37,9 +37,8 @@ namespace Debugger.Interop.CorSym @@ -37,9 +37,8 @@ namespace Debugger.Interop.CorSym
public class CorSymBinder_SxSClass : ISymUnmanagedBinder, CorSymBinder_SxS
{
// Methods
[return: MarshalAs(UnmanagedType.Interface)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
public virtual extern ISymUnmanagedReader __GetReaderForFile([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IntPtr filename, [In] IntPtr searchPath);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), PreserveSig]
public virtual extern int __GetReaderForFile([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IntPtr filename, [In] IntPtr searchPath, [Out, In, MarshalAs(UnmanagedType.IUnknown)] ref object retVal);
[return: MarshalAs(UnmanagedType.Interface)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
@ -215,9 +214,8 @@ namespace Debugger.Interop.CorSym @@ -215,9 +214,8 @@ namespace Debugger.Interop.CorSym
[ComImport, InterfaceType((short) 1), Guid("AA544D42-28CB-11D3-BD22-0000F80849BD")]
public interface ISymUnmanagedBinder
{
[return: MarshalAs(UnmanagedType.Interface)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
ISymUnmanagedReader __GetReaderForFile([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IntPtr filename, [In] IntPtr searchPath);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), PreserveSig]
int __GetReaderForFile([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IntPtr filename, [In] IntPtr searchPath, [Out, In, MarshalAs(UnmanagedType.IUnknown)] ref object retVal);
[return: MarshalAs(UnmanagedType.Interface)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
ISymUnmanagedReader __GetReaderFromStream([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In, MarshalAs(UnmanagedType.Interface)] IStream pstream);

11
src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.cs

@ -23,10 +23,17 @@ namespace Debugger.Interop.CorSym @@ -23,10 +23,17 @@ namespace Debugger.Interop.CorSym
{
IntPtr pfilename = Marshal.StringToCoTaskMemUni(filename);
IntPtr psearchPath = Marshal.StringToCoTaskMemUni(searchPath);
ISymUnmanagedReader res = symBinder.GetReaderForFile(importer, pfilename, psearchPath);
object res = null;
// The method will create the object anyway so we have to use preservesig so that we can release it
// failing to do so would lock the assembly
int code = symBinder.GetReaderForFile(importer, pfilename, psearchPath, ref res);
Marshal.FreeCoTaskMem(pfilename);
Marshal.FreeCoTaskMem(psearchPath);
return res;
if (code != 0) {
Marshal.FinalReleaseComObject(res);
throw new COMException("", code);
}
return (ISymUnmanagedReader)res;
}
// ISymUnmanagedDocument

16
src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.generated.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
@ -13,10 +13,10 @@ namespace Debugger.Interop.CorSym @@ -13,10 +13,10 @@ namespace Debugger.Interop.CorSym
{
public static partial class CorSymExtensionMethods
{
public static ISymUnmanagedReader GetReaderForFile(this CorSymBinder_SxSClass instance, object importer, IntPtr filename, IntPtr searchPath)
public static int GetReaderForFile(this CorSymBinder_SxSClass instance, object importer, IntPtr filename, IntPtr searchPath, ref object retVal)
{
ISymUnmanagedReader returnValue = instance.__GetReaderForFile(importer, filename, searchPath);
ProcessOutParameter(returnValue);
int returnValue = instance.__GetReaderForFile(importer, filename, searchPath, ref retVal);
ProcessOutParameter(retVal);
return returnValue;
}
@ -86,6 +86,7 @@ namespace Debugger.Interop.CorSym @@ -86,6 +86,7 @@ namespace Debugger.Interop.CorSym
public static void GetNamespaces(this CorSymReader_SxSClass instance, uint cNameSpaces, out uint pcNameSpaces, ISymUnmanagedNamespace[] namespaces)
{
instance.__GetNamespaces(cNameSpaces, out pcNameSpaces, namespaces);
ProcessOutParameter(namespaces);
}
public static void GetSymAttribute(this CorSymReader_SxSClass instance, uint parent, IntPtr name, uint cBuffer, out uint pcBuffer, IntPtr buffer)
@ -251,10 +252,10 @@ namespace Debugger.Interop.CorSym @@ -251,10 +252,10 @@ namespace Debugger.Interop.CorSym
instance.__UsingNamespace(fullName);
}
public static ISymUnmanagedReader GetReaderForFile(this ISymUnmanagedBinder instance, object importer, IntPtr filename, IntPtr searchPath)
public static int GetReaderForFile(this ISymUnmanagedBinder instance, object importer, IntPtr filename, IntPtr searchPath, ref object retVal)
{
ISymUnmanagedReader returnValue = instance.__GetReaderForFile(importer, filename, searchPath);
ProcessOutParameter(returnValue);
int returnValue = instance.__GetReaderForFile(importer, filename, searchPath, ref retVal);
ProcessOutParameter(retVal);
return returnValue;
}
@ -465,6 +466,7 @@ namespace Debugger.Interop.CorSym @@ -465,6 +466,7 @@ namespace Debugger.Interop.CorSym
public static void GetNamespaces(this ISymUnmanagedReader instance, uint cNameSpaces, out uint pcNameSpaces, ISymUnmanagedNamespace[] namespaces)
{
instance.__GetNamespaces(cNameSpaces, out pcNameSpaces, namespaces);
ProcessOutParameter(namespaces);
}
public static void Initialize(this ISymUnmanagedReader instance, object importer, IntPtr filename, IntPtr searchPath, IStream pIStream)

6
src/AddIns/Debugger/Debugger.Core/Interop/MetaDataWrapper.cs

@ -41,7 +41,7 @@ namespace Debugger.Interop.MetaData @@ -41,7 +41,7 @@ namespace Debugger.Interop.MetaData
ISymUnmanagedBinder symBinder = new Debugger.Interop.CorSym.CorSymBinder_SxSClass();
TrackedComObjects.Track(symBinder);
return symBinder.GetReaderForFile(metaData, fullname, searchPath);
} catch {
} catch (COMException) {
return null;
}
}
@ -52,7 +52,7 @@ namespace Debugger.Interop.MetaData @@ -52,7 +52,7 @@ namespace Debugger.Interop.MetaData
ISymUnmanagedBinder symBinder = new Debugger.Interop.CorSym.CorSymBinder_SxSClass();
TrackedComObjects.Track(symBinder);
return symBinder.GetReaderFromStream(metaData, stream);
} catch {
} catch (COMException) {
return null;
}
}
@ -66,7 +66,7 @@ namespace Debugger.Interop.MetaData @@ -66,7 +66,7 @@ namespace Debugger.Interop.MetaData
{
IMetaDataImport m = this.metaData;
if (m != null) {
Marshal.ReleaseComObject(m);
Marshal.FinalReleaseComObject(m);
metaData = null;
}
}

22
src/Tools/ComExtensionMethodGenerator/ComExtensionMethodGenerator.cs

@ -135,6 +135,7 @@ namespace ComExtensionMethodGenerator @@ -135,6 +135,7 @@ namespace ComExtensionMethodGenerator
new MemberReferenceExpression(new IdentifierExpression(ThisParameterName), method.Name)
);
// Generate arguments
bool hasProcessOuts = false;
foreach(ParameterDeclarationExpression param in method.Parameters) {
// Add argument to invocation
if (param.ParamModifier == ParameterModifiers.Ref) {
@ -159,6 +160,7 @@ namespace ComExtensionMethodGenerator @@ -159,6 +160,7 @@ namespace ComExtensionMethodGenerator
)
)
);
hasProcessOuts = true;
}
}
}
@ -167,9 +169,9 @@ namespace ComExtensionMethodGenerator @@ -167,9 +169,9 @@ namespace ComExtensionMethodGenerator
if (method.TypeReference.Type == typeof(void).FullName) {
extensionMethod.Body.Children.Insert(0, new ExpressionStatement(invoc));
} else {
if (!ProcessOutParameter ||
ProcessOutParameterIgnores.Contains(method.TypeReference.Type))
if ((!ProcessOutParameter || ProcessOutParameterIgnores.Contains(method.TypeReference.Type)) && !hasProcessOuts)
{
// Short version
extensionMethod.Body.Children.Insert(0, new ReturnStatement(invoc));
} else {
// Declare and get return value
@ -179,14 +181,16 @@ namespace ComExtensionMethodGenerator @@ -179,14 +181,16 @@ namespace ComExtensionMethodGenerator
)
);
// Call ProcessOutParameter
extensionMethod.Body.AddChild(
new ExpressionStatement(
new InvocationExpression(
new IdentifierExpression(ProcessOutParameterMethodName),
new IdentifierExpression(ReturnValueName).ToList<Expression>()
if (method.TypeReference.Type != typeof(void).FullName && !ProcessOutParameterIgnores.Contains(method.TypeReference.Type)) {
extensionMethod.Body.AddChild(
new ExpressionStatement(
new InvocationExpression(
new IdentifierExpression(ProcessOutParameterMethodName),
new IdentifierExpression(ReturnValueName).ToList<Expression>()
)
)
)
);
);
}
// Return it
extensionMethod.Body.AddChild(
new ReturnStatement(new IdentifierExpression(ReturnValueName))

Loading…
Cancel
Save