halildurmus / win32

Access common Win32 APIs directly from Dart using FFI — no C required!
https://win32.pub
BSD 3-Clause "New" or "Revised" License
760 stars 123 forks source link

WinRT generic interfaces don't project correctly #247

Closed timsneath closed 2 years ago

timsneath commented 3 years ago

See for example, Windows.Data.Xml.Dom.IXmlNodeList, which implements as follows:

interface private auto ansi abstract import windowsruntime Windows.Data.Xml.Dom.IXmlNodeList
    implements class [System.Runtime]System.Collections.Generic.IReadOnlyList`1<class [Windows.Data.winmd]Windows.Data.Xml.Dom.IXmlNode>,
               class [System.Runtime]System.Collections.Generic.IEnumerable`1<class [Windows.Data.winmd]Windows.Data.Xml.Dom.IXmlNode>
Sunbreak commented 3 years ago

AFAIK, IXmlNodeList seems to be related to IVectorView and IIterable

/*
 *
 * Interface Windows.Data.Xml.Dom.IXmlNodeList
 *
 * Introduced to Windows.Foundation.UniversalApiContract in version 1.0
 *
 * Interface is a part of the implementation of type Windows.Data.Xml.Dom.XmlNodeList
 *
 * Any object which implements this interface must also implement the following interfaces:
 *     Windows.Foundation.Collections.IVectorView`1<Windows.Data.Xml.Dom.IXmlNode>
 *     Windows.Foundation.Collections.IIterable`1<Windows.Data.Xml.Dom.IXmlNode>
 *
 */
// ...
namespace ABI {
    namespace Windows {
        namespace Data {
            namespace Xml {
                namespace Dom {
                    MIDL_INTERFACE("8c60ad77-83a4-4ec1-9c54-7ba429e13da6")
                    IXmlNodeList : public IInspectable // ...
                } /* Dom */
            } /* Xml */
        } /* Data */
    } /* Windows */
} /* ABI */

That’s a good question. ChildNodes returns an XmlNodeList, whose default interface is IXmlNodeList. IXmlNodeList requires IVectorView<IXmlNode>. For the purposes of range-based for loops, the compiler treats the result of the ChildNodes method as an IVectorView. All of the generic interfaces (like IVectorView) in the Windows::Foundation::Collections namespace have suitable begin and end free functions available to the compiler via ADL.

Sunbreak commented 3 years ago

I've tried to add IVectorView and IIterable

https://github.com/Sunbreak/win32/blob/dacc6ae1d6a36c2efe65a4670dcf8e04299418b0/tool/metadata/generate_winrt_apis.dart#L21-L22

IIterable succeeds while IVectorView fails with:

Writing:    lib\src\com\IXmlNodeList.dart
Writing:    lib\src\com\IIterable`1.dart
Unhandled exception:
WinmdException: Unrecognized or internal type 0
#0      parseCorElementType (package:winmd/src/com/constants.dart:198:7)
#1      new TypeIdentifier.fromValue (package:winmd/src/typeidentifier.dart:46:22)
#2      new TypeTuple.fromSignature (package:winmd/src/utils/typetuple.dart:30:40)
#3      Method._parseMethodDefSig (package:winmd/src/method.dart:330:21)
#4      Method._parseSignatureBlob (package:winmd/src/method.dart:272:7)
#5      new Method (package:winmd/src/method.dart:83:5)
#6      new Method.fromToken (package:winmd/src/method.dart:113:16)
#7      TypeDef.methods (package:winmd/src/typedef.dart:383:31)
#8      ClassProjector.projection (file:///C:/Users/sunbreak/Sunbreak/win32/tool/metadata/projection/classprojector.dart:84:36)
#9      main (file:///C:/Users/sunbreak/Sunbreak/win32/tool/metadata/generate_winrt_apis.dart:46:50)
#10     _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:281:32)
#11     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

It seems to be another issue

Sunbreak commented 3 years ago

Filed Fail to parse IVectorView

timsneath commented 2 years ago

Now fixed!