2012-12-27 33 views
0

時,我有以下非常簡單的接口:得到錯誤MIDL5004創建一個簡單的界面,從另一個(簡單)繼承了一個

[uuid(0d585932-fbc4-4b0a-90b5-ccf34aefd4c6)] 
[version(COMPONENT_VERSION)] 
interface IPerson : IInspectable 
{ 
    [propget] HRESULT Name([out, retval] HSTRING* value); 
    [propput] HRESULT Name([in] HSTRING value); 

    [propget] HRESULT Surname([out, retval] HSTRING* value); 
    [propput] HRESULT Surname([in] HSTRING value); 
} 

[uuid(863571FC-4CBB-47E8-8BD3-2709D5CB7D0D)] 
[version(COMPONENT_VERSION)] 
interface ICitizen : IPerson 
{ 
[propget] HRESULT Address([out, retval] IAddress** value); 
[propput] HRESULT Address([in] IAddress* value); 
} 

當我嘗試編譯此MIDL對WinRT中我得到以下錯誤:

錯誤MIDL5004:接口必須從IInspectable繼承:ICitizen

我真的WinRT的在什麼已經成爲COM的疑惑!我們如何設計應用程序,如果從另一個繼承接口這樣一個簡單的事情是不可能的?

我搜索了WinRT的MIDL文檔,但找不到它!更好的搜索谷歌錯誤MIDL5004不顯示任何結果!

任何來自Microsoft的人都可以解釋如何創建從另一個繼承自IInspectable的繼承的接口。 在另一個測試中,我創建了與C++/CX相同的接口,並且我可以創建一個繼承自IPerson的ICitizen接口。 爲什麼WinRT的MIDL不允許這樣做,這是COM架構的基礎,創建了接口的層次結構。

感謝您的輸入 O. Rouit

回答

3

所有Windows運行時接口必須從IInspectable直接派生。從另一個Windows運行時接口派生的間接派生是不可能的。

而不是使用的導出,從關係,你可以使用需要的關係,使用requires

[uuid(863571FC-4CBB-47E8-8BD3-2709D5CB7D0D)] 
[version(COMPONENT_VERSION)] 
interface ICitizen : IInspectable 
    requires IPerson 
{ 
    [propget] HRESULT Address([out, retval] IAddress** value); 
    [propput] HRESULT Address([in] IAddress* value); 
} 

這需要關係指定了一個實現ICitizen接口還必須實現IPerson接口的任何類型。但接口是獨立的,並且具有不同的(非共享的)vtable。需求關係爲1:M,因此單個接口可能要求任何實現者都實現一組M個其他接口。

+0

順便說一句,我建議你定義你的方法來獲取運行時類,而不是接口。 另外不要忘記通過mdmerge工具運行由MIDL生成的.winmd文件 - 如果不這樣做,它將無法被C++/CX,C#或JS使用。 –

+0

@LarryOsterman善意地闡明瞭爲什麼它更好地定義了接口的運行時類的方法? IIRC,ABI層的COM只處理w /接口(提供的runtimeclass參數相當於提供__INonVirtualPublic i/f作爲參數) –