We have the following APIs on Marshal
[System.CLSCompliant(false)]
public static IntPtr SecureStringToBSTR(System.Security.SecureString s) { throw null; }
[System.CLSCompliant(false)]
public static IntPtr SecureStringToCoTaskMemAnsi(System.Security.SecureString s) { throw null; }
[System.CLSCompliant(false)]
public static IntPtr SecureStringToCoTaskMemUnicode(System.Security.SecureString s) { throw null; }
[System.CLSCompliant(false)]
public static IntPtr SecureStringToGlobalAllocAnsi(System.Security.SecureString s) { throw null; }
[System.CLSCompliant(false)]
public static IntPtr SecureStringToGlobalAllocUnicode(System.Security.SecureString s) { throw null; }
public static System.IntPtr StringToBSTR(string s) { throw null; }
public static System.IntPtr StringToCoTaskMemAnsi(string s) { throw null; }
public static System.IntPtr StringToCoTaskMemAuto(string s) { throw null; }
public static System.IntPtr StringToCoTaskMemUni(string s) { throw null; }
public static System.IntPtr StringToCoTaskMemUTF8(string s) { throw null; }
public static System.IntPtr StringToHGlobalAnsi(string s) { throw null; }
public static System.IntPtr StringToHGlobalAuto(string s) { throw null; }
public static System.IntPtr StringToHGlobalUni(string s) { throw null; }
StringToCoTaskMemUTF8 is a .NET Core only API that was added before any SecureString marshalling overloads were added.
I propose that for consistency and usefuleness we add the following APIs:
public static System.IntPtr SecureStringToCoTaskMemUTF8(string s) { throw null; }
public static System.IntPtr SecureStringToGlobalAllocUTF8(string s) { throw null; }
public static System.IntPtr StringToHGlobalUTF8(string s) { throw null; }
I propose that for consistency and usefuleness we add the following APIs
public static System.IntPtr SecureStringToCoTaskMemUTF8(string s) { throw null; }
public static System.IntPtr SecureStringToGlobalAllocUTF8(string s) { throw null; }
SecureString is effectively deprecated. I don't think we should be adding new APIs for it.
@stephentoub I included this because it was mentioned in the dotnet/corefx#13485 which added back the Marshal.SecureString APIs:
https://github.com/dotnet/corefx/pull/13485#discussion_r87066957
@danmosemsft said "@tijoytom please open a separate issue for that and mark it api-needs-work or api-ready-for-review as appropriate." but an issue never got created
I included this because it was mentioned
Yup, that's fine. I still don't think we should add them ;)
Thanks for opening the issue so that I can at least express that I don't want this API either :-).
Given the comments, I think we can close this one.
Should the StringToHGlobalUTF8 be considered separately?
Thanks for pointing it - I have missed this one in the list.
StringToHGlobalUTF8 would be a duplicate API. If we were to add it, it would be just to help with discoverability a bit.
Some context:
CoTaskMemAlloc allocator has the first class support in interop. The HGlobal allocator support was always second class. For example, if you have:[DllImport(...)]
extern static string ReturnsStringAllocatedOnHeap();
The marshaling generator will assume that the string is allocated using CoTaskMemAlloc and will free it using CoTaskMemFree. There is no way to tell it to use HGlobal allocator instead.
The difference between the two allocators does not really matter these days because of both of them go into the same process global Windows heap. If you allocate memory using CoTaskMemAlloc and free it using FreeHGlobal, or vice versa, it works just fine (except if you run with old validation tools that verify that you are not mixing different allocators). There is likely a lot of programs out these that are mixing the two without even realizing it.
CoTaskMemAlloc is a bit faster than HGlobal. It does not go through as many layers.
Sounds reasonable to not add it then and just ensure the good context you provided is in docs somewhere.
Most helpful comment
Yup, that's fine. I still don't think we should add them ;)