Xtreem
asked on
Managing unmanaged memory assigned to IntPtr by Marshal::AllocHGlobal when an exception is thrown
I have the following code:
using namespace System::Runtime::InteropSe rvices;
void CRCWAssembly::CallCOMMetho d(long __gc* status)
{
try
{
IntPtr ip = Marshal::AllocHGlobal(size of(*status ));
Marshal::WriteInt32(ipStat us, *status);
(*comLib)->COMMethod(stati c_cast<lon g*>(ipStat us.ToPoint er()));
if (Marshal::ReadInt32(ipStat us) != 0)
{
throw new Exception();
}
Marshal::FreeHGlobal(ip);
}
catch(SEHException *sehEx)
{
throw new Exception("COMMethod", sehEx);
}
}
Of course, if an exception is thrown, the memory allocated to ip (IntPtr) never gets freed up. Short of wrapping it up in a class or putting Marshal::FreeHGlobal all over the place and moving the declaration of ip to outside of the 'try' block, is there any other better method to manage this unmanaged memory in the case of an exception being thrown?
using namespace System::Runtime::InteropSe
void CRCWAssembly::CallCOMMetho
{
try
{
IntPtr ip = Marshal::AllocHGlobal(size
Marshal::WriteInt32(ipStat
(*comLib)->COMMethod(stati
if (Marshal::ReadInt32(ipStat
{
throw new Exception();
}
Marshal::FreeHGlobal(ip);
}
catch(SEHException *sehEx)
{
throw new Exception("COMMethod", sehEx);
}
}
Of course, if an exception is thrown, the memory allocated to ip (IntPtr) never gets freed up. Short of wrapping it up in a class or putting Marshal::FreeHGlobal all over the place and moving the declaration of ip to outside of the 'try' block, is there any other better method to manage this unmanaged memory in the case of an exception being thrown?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks AlexFM.
I used Marshal as I am working between managed memory (*status, being passed from a C# application) and unmanaged memory (ipStatus, being passed to a COM API). This code is in the CRCW (Customer Runtime Callable Wrapper).
If I can use an unmanaged long, why does this page on MSDN show the same method I'm using for calling a COM method from a CRCW?: http://msdn2.microsoft.com/library/f31k2c87.aspx
Also, are you saying I should use Marshal::SizeOf instead of sizeof to get the size of *status?
I used Marshal as I am working between managed memory (*status, being passed from a C# application) and unmanaged memory (ipStatus, being passed to a COM API). This code is in the CRCW (Customer Runtime Callable Wrapper).
If I can use an unmanaged long, why does this page on MSDN show the same method I'm using for calling a COM method from a CRCW?: http://msdn2.microsoft.com/library/f31k2c87.aspx
Also, are you saying I should use Marshal::SizeOf instead of sizeof to get the size of *status?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Oh, I see. Well, I'd like to be consistent and make my code easily portable to other .NET languages, so for this case, I'll change sizeof to Marshal::SizeOf.
Thanks!
Thanks!
ASKER
using namespace System::Runtime::InteropSe
void CRCWAssembly::CallCOMMetho
{
IntPtr ip;
try
{
ip = Marshal::AllocHGlobal(size
Marshal::WriteInt32(ipStat
(*comLib)->COMMethod(stati
if (Marshal::ReadInt32(ipStat
{
throw new Exception();
}
Marshal::FreeHGlobal(ip);
}
catch(Exception *ex)
{
Marshal::FreeHGlobal(ip);
throw new Exception("COMMethod", ex);
}
}
But I'm still not sure that this is the ideal solution. Any more insight greatly appreciated...