You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
See #88111 for how the current generated code doesn't follow the rules.
Motivation:
To follow the ownership and lifetime expectations for COM, the generator pipeline should only assign to parameters and return values at the end of the method after unmarshalling / marshalling all parameters has succeeded. The generally recommended way to achieve this is to avoid modifying any parameters until the last basic block that returns a successful HRESULT. For our generator pipeline, this could look like an additional stage where local variables holding the final values of parameters are assigned to the parameters.
This causes slightly unexpected behavior for arrays of blittable elements that are pinned in the ManagedToUnmanaged stubs. These values could be modified if the pInvoke succeeds, but unmarshalling throws an exception. However, this may be more of a minor issue since this doesn't lead to a memory leak or double free, and can be fixed by allocating and copying all the values to a new temporary array to pass to the Unmanaged COM method.
Examples:
Assign out would look like the following for the following scenarios for ManagedToUnmanaged.
struct, blittable type / primitive: Not applicable. These values cannot pass ownership back to the caller.
reference to struct, blittable type / primitive (ref StructType parameter): <parameter> = <UnmarshalledValue>
ref StructType parameter:
// UnmarshalStructType_parameter_managed= StructTypeMarshaller.ConvertToManaged((*_parameter_native));
...// Assign out
parameter =_parameterManaged;
This could be a significant amount of work and may only be necessary for a few edge cases that are left.
Benefits:
This would make our lifetime issues much less likely and generated code would follow general COM guidance.
This also would allow us to remove ownership tracking marshalling generators like UnmanagedToManagedOwnershipTrackingStrategy
Todo:
Generate a local param_native_out variable to hold the marshalled value.
Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.
Issue Details
See #88111 for how the current generated code doesn't follow the rules.
Motivation:
To follow the ownership and lifetime expectations for COM, the generator pipeline should only assign to parameters and return values at the end of the method after unmarshalling / marshalling all parameters has succeeded. The generally recommended way to achieve this is to avoid modifying any parameters until the last basic block that returns a successful HRESULT. For our generator pipeline, this could look like an additional stage where local variables holding the final values of parameters are assigned to the parameters.
This causes slightly unexpected behavior for arrays of blittable elements that are pinned in the ManagedToUnmanaged stubs. These values could be modified if the pInvoke succeeds, but unmarshalling throws an exception. However, this may be more of a minor issue since this doesn't lead to a memory leak or double free, and can be fixed by allocating and copying all the values to a new temporary array to pass to the Unmanaged COM method.
Examples:
Assign out would look like the following for the following scenarios for ManagedToUnmanaged.
struct, blittable type / primitive: Not applicable. These values cannot pass ownership back to the caller.
reference to struct, blittable type / primitive (ref StructType parameter): <parameter> = <UnmarshalledValue>
This could be a significant amount of work and may only be necessary for a few edge cases that are left.
Benefits:
This would make our lifetime issues much less likely and generated code would follow general COM guidance.
This also would allow us to remove ownership tracking marshalling generators like UnmanagedToManagedOwnershipTrackingStrategy
See #88111 for how the current generated code doesn't follow the rules.
Motivation:
To follow the ownership and lifetime expectations for COM, the generator pipeline should only assign to parameters and return values at the end of the method after unmarshalling / marshalling all parameters has succeeded. The generally recommended way to achieve this is to avoid modifying any parameters until the last basic block that returns a successful HRESULT. For our generator pipeline, this could look like an additional stage where local variables holding the final values of parameters are assigned to the parameters.
Proposal:
The new list of stages would be:
Issues:
This causes slightly unexpected behavior for arrays of blittable elements that are pinned in the ManagedToUnmanaged stubs. These values could be modified if the pInvoke succeeds, but unmarshalling throws an exception. However, this may be more of a minor issue since this doesn't lead to a memory leak or double free, and can be fixed by allocating and copying all the values to a new temporary array to pass to the Unmanaged COM method.
Examples:
Assign out would look like the following for the following scenarios for ManagedToUnmanaged.
ref StructType parameter
): <parameter> = <UnmarshalledValue>ref StructType parameter
:ClassType[] array
:ref ClassType parameter
:And like the following for UnmanagedToManaged:
StructType* parameter
): (*<parameter>) = <MarshalledValue>StructType* value
int* array, int length
:int[]* array
/int[]* array
nint* handle
Drawbacks:
This could be a significant amount of work and may only be necessary for a few edge cases that are left.
Benefits:
This would make our lifetime issues much less likely and generated code would follow general COM guidance.
This also would allow us to remove ownership tracking marshalling generators like
UnmanagedToManagedOwnershipTrackingStrategy
Todo:
param_native_out
variable to hold the marshalled value.Track stateful marshallers for each element in unmanaged to managed stubs #89462ComInterfaceGenerator should warn when a collection's element marshaller is stateful #89465The text was updated successfully, but these errors were encountered: