gpt4 book ai didi

windows-runtime - 如何声明继承自 IClosable/IDisposable 的接口(interface)

转载 作者:行者123 更新时间:2023-12-01 03:59:13 25 4
gpt4 key购买 nike

this question 中被告知我首选的解决方案是不可能的后,我现在正在尝试实现一种解决方法。我没有在 C++/CX 中声明从 IClosable 继承的接口(interface),而是在原始 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 ;
}
}

最佳答案

如果您在 cmds 中添加对 mdmerge 的调用,它应该可以工作:

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;
}
};
}

midlrt 生成的原始 FooSpace.winmd 文件引用 Windows.Foundation (C:\Windows\system32\WinMetadata\Windows.Foundation.winmd),而 mdmerge 输出引用 Windows (C:\Program Files (x86)\Windows Kits\8.0\References\CommonConfiguration\Neutral\Windows.winmd)。

有趣的是,您能够毫无问题地引用 c# 项目中的mildrt-output winmd 文件,因为在博客文章 How to reference C++ WRL Components from a .NET project 中Kevin Stumpf 描述了他在不先使用 mdmerge 时遇到了一些问题。

关于windows-runtime - 如何声明继承自 IClosable/IDisposable 的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14653250/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com