Description
Background and motivation
It is currently quite hard to reclaim memory allocated internally by the Marshal.GetNativeVariantForObject
method. Let's take the following code as an example:
var variantPtr = Marshal.AllocHGlobal(VariantTypeSize); // VariantTypeSize = 24 (x64) or 16 (x86)
Marshal.GetNativeVariantForObject("test string", variantPtr);
// pass the variantPtr to native code and do the work
Marshal.FreeHGlobal(variantPtr);
We are leaking memory because GetNativeVariantForObject
assigns the string to the AsBstr
property of the internal Variant
type. The AsBstr
property internally allocates memory using Marshal.StringToBSTR
. One solution could be to provide the Marshal.FreeNativeVariant
method, which would reclaim the internal memory.
API Proposal
namespace System.Runtime.InteropServices;
public static class Marshal
{
public static void FreeNativeVariant(nint addr);
}
API Usage
var variantPtr = Marshal.AllocHGlobal(VariantTypeSize); // VariantTypeSize = 24 (x64) or 16 (x86)
Marshal.GetNativeVariantForObject("test string", variantPtr);
// pass the variantPtr to native code and do the work
Marshal.FreeNativeVariant(variantPtr);
Marshal.FreeHGlobal(variantPtr);
Alternative Designs
Another approach that comes to my mind is to modify the BStrWrapper
class so it will be responsible for allocating and freeing memory for the wrapped BSTR string. Then we would need to instruct the users to use the wrapper when calling GetNativeVariantForObject
as using raw string leads to a leak. GetNativeVariantForObject
already accepts BStrWrapper
, so we won't need to modify the public API.
Risks
No response
Metadata
Metadata
Assignees
Type
Projects
Status