Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API Proposal]: Provide API for freeing Variant memory #79402

Open
lowleveldesign opened this issue Dec 8, 2022 · 2 comments
Open

[API Proposal]: Provide API for freeing Variant memory #79402

lowleveldesign opened this issue Dec 8, 2022 · 2 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Runtime.InteropServices
Milestone

Comments

@lowleveldesign
Copy link

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

@lowleveldesign lowleveldesign added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Dec 8, 2022
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Dec 8, 2022
@ghost
Copy link

ghost commented Dec 9, 2022

Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.

Issue Details

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

Author: lowleveldesign
Assignees: -
Labels:

api-suggestion, area-System.Runtime.InteropServices, untriaged

Milestone: -

@AaronRobinsonMSFT
Copy link
Member

This is handled in Win32 via VariantClear(). When marshaling through the IL Stubs this is handled by the VM itself. It does seem like a missing low-level API. I'm not sure it is worth adding given how long it has been missing, but we can see how the community responds.

@AaronRobinsonMSFT AaronRobinsonMSFT removed the untriaged New issue has not been triaged by the area owner label Dec 9, 2022
@AaronRobinsonMSFT AaronRobinsonMSFT added this to the Future milestone Dec 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Runtime.InteropServices
Projects
Status: No status
Development

No branches or pull requests

3 participants