2015-02-18 8 views
0

У меня есть проект Dll с интерфейсами IDL. Я хочу иметь интерфейсы в моей dll, что один из них может быть получен из другого. Я создал два интерфейса с ATL Simple Object Wizard.Как создать два интерфейса ATL, полученных от другого?

[ 
    object, 
    uuid(7359AF6C-6E90-4372-991F-556602CB3977), 
    dual, 
    nonextensible, 
    pointer_default(unique) 
] 
interface IZInterface : IDispatch{ 
    [id(1)] HRESULT ZGetStr([out,retval] BSTR* str); 
    [id(2)] HRESULT GetSize([in,out] LONG* nSize); 
}; 
[ 
    object, 
    uuid(8CA6DBF2-E402-464D-96AE-3D6642D91E14), 
    pointer_default(unique) 
] 
interface IBClass : IUnknown{ 
    [] HRESULT Method11([out,retval] LONG* l); 
}; 
library DllStandardLib 
{ 
    importlib("stdole2.tlb"); 
    [ 
     uuid(491DF659-012F-4C20-90AA-0CBC5BDE5A68)  
    ] 
    coclass ZInterface 
    { 
     [default] interface IZInterface; 
    }; 
     [ 
     uuid(43CE897F-17F2-4D45-9098-26B7AEE6EC23)  
    ] 
    coclass BClass 
    { 
     [default] interface IBClass; 
    }; 
}; 

сейчас, я нажимаю правой кнопкой мыши на CZInterface в представлении класса, а затем в интерфейсе Impelement IBClass.

но в continer, который является # проект C:

DllStandardLib.ZInterface dd = new DllStandardLib.ZInterface(); 
dd.Method11();//---> Error: DllStandardLib.ZInterface' does not contain a definition for 'Method11' and no extension method 'Method11' accepting a first argument of type ... 

что проблема в моем проекте? Я хочу, чтобы второй (производный) интерфейс знал все методы и свойства базового интерфейса. , пожалуйста, помогите мне!

+0

IBClass происходит от IUnknown, а не от IZInterface. Так что, конечно, это не сработает. Мастер ATL не поможет вам это сделать, вам нужно сделать это вручную. Может, не стоит. –

ответ

1

Лучше всего не использовать Мастер объектов, если вы хотите достичь этого. Сначала определите свои интерфейсы:

[ 
    object, 
    uuid(7359AF6C-6E90-4372-991F-556602CB3977), 
    dual, 
    nonextensible, 
    pointer_default(unique) 
] 
interface IZInterface : IDispatch 
{ 
    [id(1)] HRESULT ZGetStr([out,retval] BSTR* str); 
    [id(2)] HRESULT GetSize([in,out] LONG* nSize); 
}; 

[ 
    object, 
    uuid(8CA6DBF2-E402-464D-96AE-3D6642D91E14), 
    pointer_default(unique) 
] 
interface IBClass : IZInterface // IBClass inherits from IZInterface 
{ 
    [id(3)] HRESULT Method11([out,retval] LONG* l); 
}; 

Затем определите свой класс, который реализует специализированный интерфейс. Сделайте это в вашей библиотеке:

library DllStandardLib 
{ 
    importlib("stdole2.tlb"); 

    [ 
     uuid(43CE897F-17F2-4D45-9098-26B7AEE6EC23)  
    ] 
    coclass BClass 
    { 
     [default] interface IBClass; 
    }; 

    // NOTE: No need for ZInterface coclass. 
}; 

Обратите внимание, что IZInterface класс на самом деле не нужно, за исключением того, вы хотите, чтобы обеспечить отдельную реализацию (= другой класс).

Для того, чтобы QueryInterface -calls работать, вы должны также добавить интерфейс к вашему COM интерфейс карты:

class CBClass : 
    // ... 
{ 
    // ... 

BEGIN_COM_MAP(CBClass) 
    COM_INTERFACE_ENTRY(IBClass) 
    COM_INTERFACE_ENTRY(IZInterface) 
END_COM_MAP() 

    // ... 

    // IBClass-Member 
    STDMETHOD(Method11)(LONG* l); // Implement this in your source file (STDMETHODIMP CBClass::Method11(LONG* l) { return E_NOTIMPL; } 
} 

Для вызова ваших IBClass членов интерфейса с .NET, вы должны создать экземпляр правый класс:

DllStandardLib.BClass bc = new DllStandardLib.BClass(); 
bc.Method11(); 
+0

'ATL :: CComObject ': не может создать экземпляр абстрактного класса – nabegheh95

+0

@ nabegheh95: Вам также нужно добавить определение и объявление 'Method11' в свой класс;) Я также обновил ответ! – Carsten

+0

Затем, что я пишу в ZInterface.h и ZInterface.cpp? – nabegheh95