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

Create wrappers for VARIANT and PROPVARIANT structures #820

Open
halildurmus opened this issue Feb 24, 2024 · 1 comment
Open

Create wrappers for VARIANT and PROPVARIANT structures #820

halildurmus opened this issue Feb 24, 2024 · 1 comment
Assignees
Labels
com Issue with COM support feature A new feature or request P2 Medium-priority issue package: win32 Issue with package:win32
Milestone

Comments

@halildurmus
Copy link
Owner

halildurmus commented Feb 24, 2024

VARIANT and PROPVARIANT structures are widely used in COM APIs as containers for various types of data. These structures consist of a large union to represent different types efficiently.

For example, here’s how you would create a VARIANT struct to hold a BSTR (a COM string type):

final variant = calloc<VARIANT>();
variant.ref
  ..vt = VARENUM.VT_BSTR // Define the type of the VARIANT
  ..bstrVal = BSTR.fromString('I am a happy BSTR').ptr; // Set the value

// Do something with the VARIANT...

// Clean up
VariantClear(variant);
calloc.free(variant);

While this works, it’s verbose and prone to errors, especially when dealing with memory allocation and cleanup. We could create wrapper classes for these structures and use NativeFinalizer to handle memory management automatically. These wrappers should also include detach and free methods, giving users greater control over the object's lifecycle.

Here's how the wrapper class for VARIANT could look like:

final class Variant<T extends Object?> implements Finalizable {
  /// Creates a new empty [Variant].
  ///
  /// The constructed [VARIANT] will have the [VT_EMPTY] type.
  ///
  /// Attaches a [NativeFinalizer] to the instance to automatically free the
  /// memory when no longer used.
  factory Variant() => Variant.fromPointer(calloc<VARIANT>());

  factory Variant.from(T value) => Variant<T>()..value = value;

  Variant.fromPointer(this.ptr) {
    _finalizer.attach(
      this,
      ptr.cast(),
      detach: this,
      externalSize: sizeOf<VARIANT>(),
    );
  }

  static final _finalizer = NativeFinalizer(...);

  final Pointer<VARIANT> ptr;

  void detach() => _finalizer.detach(this);

  void free() {
    _finalizer.detach(this);
    VariantClear(ptr);
    calloc.free(ptr);
  }

  static VariantBSTR bstr(String value) => VariantBSTR(value);

  T get value {
    // ...
  }

  set value(T value) {
    // ...
  }

  // ...
}

final class VariantBSTR extends Variant<String?> {
  factory VariantBSTR(String value) {
    final variant = calloc<VARIANT>();
    variant.ref
      ..vt = VT_BSTR
      ..bstrVal = value.toBSTR();
    return VariantBSTR.fromPointer(variant);
  }

  VariantBSTR.fromPointer(super.ptr) : super.fromPointer();

  @override
  String? get value => bstrVal.isNull ? null : bstrVal.toDartString();
  @override
  set value(String? value) => bstrVal = value?.toBSTR() ?? nullptr;
}

// ...

With this wrapper, creating and using a VARIANT becomes much easier:

final variant = Variant.bstr('I am a happy BSTR');
// Or:
// final variant = Variant.from('I am a happy BSTR');

// Do something with the VARIANT...
@halildurmus halildurmus added feature A new feature or request com Issue with COM support labels Feb 24, 2024
@halildurmus halildurmus added this to the 6.0.0 milestone Feb 24, 2024
@halildurmus halildurmus self-assigned this Feb 24, 2024
@android-dev2015
Copy link

I just encountered this similar problem,haha

@halildurmus halildurmus modified the milestone: 6.0.0 Aug 6, 2024
@halildurmus halildurmus added the package: win32 Issue with package:win32 label Oct 18, 2024
@halildurmus halildurmus added the P2 Medium-priority issue label Jan 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
com Issue with COM support feature A new feature or request P2 Medium-priority issue package: win32 Issue with package:win32
Projects
None yet
Development

No branches or pull requests

2 participants