Может ли интерфейс C++/CX наследоваться от IClosable?

Как объявить интерфейс времени выполнения, который наследуется от Windows.Foundation.IClosable в C++/CX?

Обе эти попытки приводят к ошибкам компилятора:

public interface class MyInterface : Windows::Foundation::IClosable {
   /* bla bla */
};
==> error C2039: 'IClosable' : is not a member of 'Windows::Foundation'

а также

public interface class MyInterface {
   /* bla bla */
   ~MyInterface();
};
==> error C2849: 'MyInterface' : an interface cannot have a destructor

Однако не может быть, чтобы такое наследование было категорически запрещено в среде выполнения Windows, потому что некоторые предоставляемые системой интерфейсы наследуются от IClosable, например IInputStream.

Я полагаю, что вместо этого я мог бы определить MyInterface в IDL и преобразовать его во внешний файл .winmd с помощью midlrt.exe перед компиляцией кода C++. Однако это было бы нежелательной компиляцией моего процесса сборки. Есть ли способ указать это как источник C++/CX?


person hmakholm left over Monica    schedule 29.01.2013    source источник
comment
Windows::Foundation::IClosable сопоставляется с Platform::IDisposable. Если ref class имеет общедоступный деструктор, компилятор автоматически заставит этот класс реализовать этот интерфейс и сопоставит член Close/Dispose с уничтожением. Чего вы пытаетесь достичь, заставляя исполнителя MyInterface также реализовывать IClosable?   -  person James McNellis    schedule 30.01.2013
comment
@JamesMcNellis: есть сопоставление изменения имени (на System.IDisposable), задокументированное для .NET, но не для C++/CX. Во всяком случае, написание Platform::IDisposable вместо этого просто дает мне еще одну ошибку компилятора, говорящую мне вместо этого объявить деструктор - но, как показывает второй пример, это тоже не работает. Чего я пытаюсь добиться, так это пообещать пользователю моего кода, что он может вызывать Close() на MyInterface, который я ему дам, чтобы он мог использовать любую уже существующую инфраструктуру на основе IClosable для ее вызова, которую он уже может есть в его распоряжении.   -  person hmakholm left over Monica    schedule 30.01.2013
comment
Итак, это невозможно сделать на C++/CX. К сожалению, моя попытка обходного пути тоже не сработала: Дополнительный вопрос   -  person hmakholm left over Monica    schedule 01.02.2013


Ответы (1)


Вы можете наследовать от IClosable, только если вы не используете C++/CX.

Причина, по которой вы получаете первую ошибку, заключается в том, что этот интерфейс не является частью метаданных Windows.winmd. Этот интерфейс объявлен в пространстве имен ABI::Windows::Foundation файла windows.foundation.h.

Вторая ошибка возникает из-за того, что интерфейс не может иметь деструктор.

MSDN: когда вы объявляете общедоступный деструктор, компилятор генерирует код, чтобы класс ссылки реализовывал Platform::IDisposable, а деструктор реализовывал метод Dispose. Platform::IDisposable — это C++/CX-проекция Windows::Foundation::IClosable. Никогда не реализуйте эти интерфейсы явно.

person maxim pg    schedule 30.01.2013
comment
Интерфейс, безусловно, является частью Windows.winmd. Объявление для него присутствует в дампе Windows.winmd, который создает ildasm.exe. - person hmakholm left over Monica; 30.01.2013
comment
Возможно, он есть, но спрятан. Компилятор C++ не смог найти его. - person maxim pg; 30.01.2013