-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Closed
Closed
Copy link
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-System.Runtime.InteropServices
Milestone
Description
Background and motivation
Add BSTR marshaller in addition to new string marshallers in #67635. Since this marshaller is for adoption purposes it is similar to the existing ANSI marshaller and will require users to manually define it using MarshalUsing attribute or can rely on the UnmanagedType.BStr value in a MarshalAs.
API Proposal
Implementation PR - #69213
namespace System.Runtime.InteropServices.Marshalling
{
/// <summary>
/// Marshaller for BSTR strings
/// </summary>
[CLSCompliant(false)]
[CustomTypeMarshaller(typeof(string), BufferSize = 0x100,
Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.TwoStageMarshalling | CustomTypeMarshallerFeatures.CallerAllocatedBuffer)]
public unsafe ref struct BStrStringMarshaller
{
/// <summary>
/// Initializes a new instance of the <see cref="BStrStringMarshaller"/>.
/// </summary>
/// <param name="str">The string to marshal.</param>
public BStrStringMarshaller(string? str);
/// <summary>
/// Initializes a new instance of the <see cref="BStrStringMarshaller"/>.
/// </summary>
/// <param name="str">The string to marshal.</param>
/// <param name="buffer">Buffer that may be used for marshalling.</param>
/// <remarks>
/// The <paramref name="buffer"/> must not be movable - that is, it should not be
/// on the managed heap or it should be pinned.
/// <seealso cref="CustomTypeMarshallerFeatures.CallerAllocatedBuffer"/>
/// </remarks>
public BStrStringMarshaller(string? str, Span<ushort> buffer);
/// <summary>
/// Returns the native value representing the string.
/// </summary>
/// <remarks>
/// <seealso cref="CustomTypeMarshallerFeatures.TwoStageMarshalling"/>
/// </remarks>
public void* ToNativeValue();
/// <summary>
/// Sets the native value representing the string.
/// </summary>
/// <param name="value">The native value.</param>
/// <remarks>
/// <seealso cref="CustomTypeMarshallerFeatures.TwoStageMarshalling"/>
/// </remarks>
public void FromNativeValue(void* value);
/// <summary>
/// Returns the managed string.
/// </summary>
/// <remarks>
/// <seealso cref="CustomTypeMarshallerDirection.Out"/>
/// </remarks>
public string? ToManaged();
/// <summary>
/// Frees native resources.
/// </summary>
/// <remarks>
/// <seealso cref="CustomTypeMarshallerFeatures.UnmanagedResources"/>
/// </remarks>
public void FreeNative();
}
}API Usage
The following is an example from aspnetcore where this new marshaller could be used.
[LibraryImport(AspNetCoreModuleDll)]
private static partial int http_get_server_variable(
NativeSafeHandle pInProcessHandler,
[MarshalAs(UnmanagedType.LPStr)] string variableName,
[MarshalUsing(typeof(BStrStringMarshaller))] out string value);
// or
[LibraryImport(AspNetCoreModuleDll)]
private static partial int http_get_server_variable(
NativeSafeHandle pInProcessHandler,
[MarshalAs(UnmanagedType.LPStr)] string variableName,
[MarshalAs(UnmanagedType.BStr)] out string value);Alternative Designs
No response
Risks
None. This is a new opt-in API.
Metadata
Metadata
Assignees
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-System.Runtime.InteropServices