-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Use System.Runtime.InteropServices.Marshalling.ComVariant instead of custom VARIANT types in libraries #123060
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
base: main
Are you sure you want to change the base?
Conversation
…a local PROPVARIANT type in System.Data.OleDb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request replaces custom VARIANT and PROPVARIANT type definitions in System.DirectoryServices and System.Data.OleDb libraries with the standard ComVariant type from System.Runtime.InteropServices.Marshalling. This unification follows interop best practices for representing Win32 VARIANT types.
Key changes:
- Removed custom
VariantandPROPVARIANTstruct definitions and replaced them withComVariant - Consolidated VARIANT and PROPVARIANT handling in OleDb to use the same cleanup code path
- Updated all usages to call
ComVariant.Create()andComVariant.Dispose()instead of manual struct initialization and native cleanup functions
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryEntry.cs | Replaced manual VARIANT initialization with ComVariant.Create(true) |
| src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj | Removed references to VariantClear and VariantInit interop files |
| src/libraries/System.DirectoryServices/src/Interop/UnsafeNativeMethods.cs | Removed custom Variant struct and updated IAdsObjectOptions2 to use ComVariant |
| src/libraries/System.DirectoryServices/src/Interop/EnumVariant.cs | Updated to use ComVariant with proper disposal pattern |
| src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj | Removed references to VariantClear and PropVariantClear interop files |
| src/libraries/System.Data.OleDb/src/SafeHandles.cs | Removed entire PROPVARIANT struct definition and related types (307 lines) |
| src/libraries/System.Data.OleDb/src/RowBinding.cs | Consolidated VARIANT and PROPVARIANT cleanup to use single code path with ComVariant |
| src/libraries/System.Data.OleDb/src/PropertyInfoSet.cs | Updated to use ComVariant.Dispose() instead of VariantClear |
| src/libraries/System.Data.OleDb/src/OleDb_Util.cs | Updated SizeOf_Variant calculation to use Unsafe.SizeOf() |
| src/libraries/System.Data.OleDb/src/OleDb_Enum.cs | Updated D_PropVariant size to use sizeof(ComVariant) |
| src/libraries/System.Data.OleDb/src/DbPropSet.cs | Updated to use ComVariant.Dispose() instead of VariantClear |
| src/libraries/System.Data.OleDb/src/DbBindings.cs | Updated comments to reference ComVariant instead of PROPVARIANT |
| src/libraries/Common/src/Interop/Windows/OleAut32/Interop.VariantInit.cs | Deleted file - no longer needed with ComVariant |
|
Tagging subscribers to this area: @dotnet/interop-contrib |
| ref ComVariant variant = ref *(ComVariant*)vptr; | ||
| variant.Dispose(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this better? Passing the IntPtr to a well-defined P/Invoke seems a lot clearer rather than casting to some interop type and calling Dispose().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I initially made this change with the intent to swap other usages of the PROPVARIANT type to the new API. I later realized that the only usages of it were for size calculations (and actually fetching the value into a .NET value was done with Marshal.GetObjectForNativeVariant. I'll revert the Dispose changes back to using PropVariantClear.
| internal static readonly int SizeOf_tagDBPROPIDSET = Marshal.SizeOf<tagDBPROPIDSET>(); | ||
| internal static readonly int SizeOf_Guid = Marshal.SizeOf<Guid>(); | ||
| internal static readonly int SizeOf_Variant = 8 + (2 * IntPtr.Size); // 16 on 32bit, 24 on 64bit | ||
| internal static readonly int SizeOf_Variant = Unsafe.SizeOf<ComVariant>(); // 16 on 32bit, 24 on 64bit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| internal static readonly int SizeOf_Variant = Unsafe.SizeOf<ComVariant>(); // 16 on 32bit, 24 on 64bit | |
| internal static readonly int SizeOf_Variant = Unsafe.SizeOf<ComVariant>(); |
| { | ||
| IntPtr valuePtr = ADP.IntPtrOffset(infoPtr, (k * ODB.SizeOf_tagDBPROPINFO) + ODB.OffsetOf_tagDBPROPINFO_Value); | ||
| Interop.OleAut32.VariantClear(valuePtr); | ||
| ref ComVariant variant = ref *(ComVariant*)valuePtr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
OleDb and DirectoryServices were using their own representations of the Win32 VARIANT and PROPVARIANT types. Unify on the ComVariant type as it follows interop best practices to map the Win32 VARIANT type.