Windows runtime 如何声明从IClosable/IDisposable继承的接口
在被告知我首选的解决方案不可能实现后,我现在正在尝试实施一种变通方法。我不是在C++/CX中声明从IClosable继承的接口,而是在原始IDL中声明它。但这似乎也不起作用 我已经创建了一个IDL文件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
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时遇到的一些问题