none
Safe IntPtr handle

    Question

  • I wrote the class which is supposed to be used as IntPtr wrapper. It should keep result of Marshal.AllocHGlobal operation, and calls Marshal.FreeHGlobal when instance is disposed or finalized. Class is tested and appears to work properly in different situations.

    I want to ask C# gurus to take a look at this class and post opinions about it: C# programming style, safety etc. - something that I possibly missed.

     

       /// <summary>
        /// IntPtr wrapper which can be used as result of
        /// Marshal.AllocHGlobal operation.
        /// Call Marshal.FreeHGlobal when disposed or finalized.
        /// </summary>
        class HGlobalSafeHandle : SafeHandle
        {
            /// <summary>
            /// Creates new instance with given IntPtr value
            /// </summary>
            public HGlobalSafeHandle(IntPtr ptr) : base(ptr, true)
            {
            }

            /// <summary>
            /// Creates new instance with zero IntPtr
            /// </summary>
            public HGlobalSafeHandle() : base(IntPtr.Zero, true)
            {
            }

            /// <summary>
            /// Creates new instance which allocates unmanaged memory of given size

          /// Can throw OutOfMemoryException - is this bad, any idea how to do this better?
            /// </summary>
            public HGlobalSafeHandle(int size) :
                base(Marshal.AllocHGlobal(size), true)
            {
            }


            /// <summary>
            /// Allows to assign IntPtr to HGlobalSafeHandle
            /// </summary>
            public static implicit operator HGlobalSafeHandle(IntPtr ptr)
            {
                return new HGlobalSafeHandle(ptr);
            }

            /// <summary>
            /// Allows to use HGlobalSafeHandle as IntPtr
            /// </summary>
            public static implicit operator IntPtr(HGlobalSafeHandle h)
            {
                return h.handle;
            }

            /// <summary>
            /// Called when object is disposed or finalized.
            /// </summary>
            override protected bool ReleaseHandle()
            {
                Marshal.FreeHGlobal(handle);
                return true;
            }

            /// <summary>
            /// Defines invalid (null) handle value.
            /// </summary>
            public override bool IsInvalid
            {
                get
                {
                    return (handle == IntPtr.Zero);
                }
            }
        }

    Monday, July 23, 2007 5:28 PM

Answers

All replies

  • Generally looks decent, though really you should inherit from the rather verbosely named SafeHandleZeroOrMinusOneIsInvalid class rather than just SafeHandle.
    Monday, July 23, 2007 7:23 PM
  • Hi Greg,

    Hope you are doing good. I need some help on pInvoke side.

    I am facing issue using SafeHandleZeroOrMinusOneIsInvalid when using from C# code to call C++ code using pInvoke. I am getting AccessViolation exception on Window 7 64 bit machine. It works fine on Windows XP.

    I have derived my class CryptoHandle from the above class and used as the return type (pointer to C++ class). The class is a CryptoU class with methods to use CryptoPP (third party C++ library - cryptopp.com )

    When I am passing the CryptoHandle instance to a pInvoke method to call destructor on the C++ class, it calls delete on the instance and it deletes below class variables...

    if(m_pServerPubKey != NULL)
    	{
    		delete m_pServerPubKey;
    		m_pServerPubKey = NULL;		
    	}
    	if(m_pPrivKey != NULL)
    	{
    		delete m_pPrivKey;
    		m_pPrivKey = NULL;
    	}

    RSAES_PKCS1v15_Encryptor* m_pServerPubKey and RSAES_PKCS1v15_Decryptor* m_pPrivKey

    I am getting exception when below line gets executed

    delete m_pServerPubKey;

    Do you think I am using SafeHandle wrong way or do u think the issue might be in the third party library?

    Let me know if you need more info on the same.

    Appreciate your time and help.

    Thanks,
    Jit


    Jit
    • Edited by jitman Tuesday, January 03, 2012 9:48 PM
    Tuesday, January 03, 2012 9:43 PM
  • I would recommend you post this as a new question in order to get a faster response. This is already marked as answered.
    Tuesday, January 03, 2012 10:02 PM
  • I am doing it. Thanks.
    Jit
    Tuesday, January 03, 2012 10:15 PM