Windows runtime 如何声明从IClosable/IDisposable继承的接口

Windows runtime 如何声明从IClosable/IDisposable继承的接口,windows-runtime,c++-cx,Windows Runtime,C++ Cx,在被告知我首选的解决方案不可能实现后,我现在正在尝试实施一种变通方法。我不是在C++/CX中声明从IClosable继承的接口,而是在原始IDL中声明它。但这似乎也不起作用 我已经创建了一个IDL文件FooSpace.IDL包含 import "inspectable.idl"; import "Windows.Foundation.idl"; namespace FooSpace { [uuid(01234567-89AB-CDEF-FEDC-BA9876543210)] [v

在被告知我首选的解决方案不可能实现后,我现在正在尝试实施一种变通方法。我不是在C++/CX中声明从IClosable继承的接口,而是在原始IDL中声明它。但这似乎也不起作用

我已经创建了一个IDL文件
FooSpace.IDL
包含

import "inspectable.idl";
import "Windows.Foundation.idl";
namespace FooSpace
{
    [uuid(01234567-89AB-CDEF-FEDC-BA9876543210)]
    [version(42)]
    interface Foo : IInspectable requires Windows.Foundation.IClosable
    {
    }
}
并使用从中生成Windows运行时元数据

midlrt /nomidl /metadata_dir "C:\Program Files (x86)\Windows Kits\8.0\References\CommonConfiguration\Neutral" FooSpace.idl
生成的
FooSpace.winmd
在我使用
ildasm
对其进行反汇编时看起来还不错——特别是,
Foo
似乎继承自
IClosable
,与
IInputStream
在提供的
Windows.winmd
系统中的继承方式相同

然而,当我试图从C++/CX使用它时——甚至没有实现它,只是暂时假装其他人用WRL或其他什么实现了它——它似乎不起作用。这是我的测试C++/CX源文件:

void works(Windows::Storage::Streams::IInputStream^ istream) {
  Platform::IDisposable^ local = istream ;
}
void doesnt(FooSpace::Foo^ foo) {
  Platform::IDisposable^ local = foo ;
}
这会为
Foo
生成错误,但不会为
IInputStream
生成错误:

C:\cygwin\tmp>cl /nologo /c /ZW /FU FooSpace.winmd  testit.cpp
testit.cpp
testit.cpp(5) : error C2440: 'initializing' : cannot convert from 'FooSpace::Foo ^' to 'Platform::IDisposable ^'
        No user-defined-conversion operator available, or
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
我做错了什么


另一方面,等效的C#代码似乎编译得很好:

public class Whatever {
  public static void Works(Windows.Storage.Streams.IInputStream istream) {
    System.IDisposable local = istream ;
  }
  public static void AlsoWorks(FooSpace.Foo foo) {
    System.IDisposable local = foo ;
  }
}

如果将对mdmerge的调用添加到cmds中,则该调用应能正常工作:

midlrt /nomidl /metadata_dir "C:\Program Files (x86)\Windows Kits\8.0\References\CommonConfiguration\Neutral" FooSpace.idl
mdmerge -metadata_dir "C:\Program Files (x86)\Windows Kits\8.0\References\CommonConfiguration\Neutral" -i "." -o "merged" -v -partial
cl /nologo /c /ZW /FU merged\FooSpace.winmd /EHsc testit.cpp
使用“合并”winmd文件,我可以编译如下代码:

namespace ClosableTest
{
    ref class Test sealed
        : FooSpace::Foo
    {
    public: 
        virtual ~Test()
        {
           FooSpace::Foo^ f = nullptr;
           Platform::IDisposable^ d = f;
        }
    };
}

原始的FoSPAC.WINMD文件,它由MIDLRT引用Windows .Fund(C:\Windows \ Stave3\WINMIDELT\WINDOWS .FAST.WINMD)生成,而MDEMLO输出引用窗口(C:\程序文件(x86)\ Windows工具包\ 8个引用\公共配置\Noal\WINDOWS .WINMD”.< 有趣的是,您能够在c#项目中毫无问题地引用mildrt输出winmd文件,因为Kevin Stumpf在博客文章中描述了他在不首先使用mdmerge时遇到的一些问题