Open jlaanstra opened 2 years ago
I was hitting this same issue, and after debugging and some internal discussions, the issue lies in the metadata-based marshalling (aka WinMD). It is currently unable to make the connection between IVector<Foo>
and IIterable<Foo>
for custom Foo
. Given that, I don't think that CsWinRT can do much here (although I am not the owner of that decision).
There are two workarounds that I am aware of.
The path that I know of requires the marshalling side to be packaged, although there may also be a method using binary manifests to achieve the same result. The AppxManifest.xml file for the package can be enlightened with something like the following:
<?xml version="1.0" encoding="utf-8"?>
<Package ...>
...
<Extensions>
<Extension Category="windows.activatableClass.proxyStub">
<ProxyStub ClassId="00000355-0000-0000-C000-000000000046">
<Path>YOUR.WINMD.winmd</Path>
<Interface Name="Windows.Foundation.Collections.IIterable`1<YOUR.TYPE>" InterfaceId="GENERATED.IID" />
...
</ProxyStub>
</Extension>
<!-- This entry forces the package registration to process the windows.activatableClass.proxyStub extension above. -->
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>YOUR.DLL.dll</Path>
<ActivatableClass ActivatableClassId="Placeholder.Activatable.Class.Do.Not.Use" ThreadingModel="STA" />
</InProcessServer>
</Extension>
</Extensions>
...
</Package>
00000355-0000-0000-C000-000000000046
is a the GUID for metadata-based marshalling.YOUR.WINMD.winmd
should be the one containing YOUR.TYPE
YOUR.TYPE
is a type in an IVector
or IVectorView
(or any container that you might want to iterate).GENERATED.IID
is the interface identifier that is generated for this parameterized type. I wouldn't try to calculate this myself, but instead use CsWinRT/CppWinRT (I wrote some code to spit out winrt::name_of<T>
and winrt::guid_of<T>
for everything we expose), or even the debugger on the server (although this is slow).
Interface
for every type you want to be iterable.YOUR.DLL
is a dll in your package, but it will not be used. This is a dummy registration to force the proxy-stub extension to be processed.Don't use IIterable
(aka IEnumerable
in .Net).
for (int i = 0; i < myVector.Size; ++i)
{
var obj = myVector[i];
... use obj ...
}
Describe the bug When enumerating an out-of-process vector an exception "No such interface supported" is thrown.
To Reproduce Repro shared offline.
Expected behavior No exceptions thrown.
Version Info 1.6.4
Additional context N/A