Click here to Skip to main content
15,881,715 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,
I have a DLL Project with IDL interfaces.
I want to have two interfaces in my dll so that one of them can be derived from another.
I created two interfaces with ATL Simple Object Wizard.
C++
[
    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;
	};
};


Now, I right-click on the CZInterface in the Class View, then I select "Impelement Interface IBClass".

But in a container that is a C# project:
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 ...


What is the problem with my project? I want that the second (derived) interface would know all the methods and properties of the base interface.

Please, help me!
Posted
Updated 17-Feb-15 22:22pm
v2

1 solution

The problem is that your IZInterface is not derived (according to your code) from IBClass, therefore it doesn't have the method Method1. Your code should look something like
C++
[
	object,
	uuid(8CA6DBF2-E402-464D-96AE-3D6642D91E14),
	pointer_default(unique)
]
interface IBClass : IDispatch{
	[] HRESULT Method11([out,retval] LONG* l);
};
[
    object,
    uuid(7359AF6C-6E90-4372-991F-556602CB3977),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface IZInterface : IBClass{//it's derived from IBClass, see?
    [id(1)] HRESULT ZGetStr([out,retval] BSTR* str);
    [id(2)] HRESULT GetSize([in,out] LONG* nSize);
};
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;
	};
};

Thanks to Microsoft "The current implementation of MIDL does not handle function overloading or multiple inheritance". So your IBClass can be inherited from IDispatch rather than from IUnknown. But you can try to emulate multiple inheritance by writing some of your classes in C++. For example, here is the definition of IDispatch from OAIdl.h
C++
MIDL_INTERFACE("00020400-0000-0000-C000-000000000046")
IDispatch : public IUnknown
{
public:
    virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(
        /* [out] */ __RPC__out UINT *pctinfo) = 0;

    virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(
        /* [in] */ UINT iTInfo,
        /* [in] */ LCID lcid,
        /* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo) = 0;

    virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(
        /* [in] */ __RPC__in REFIID riid,
        /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
        /* [range][in] */ __RPC__in_range(0,16384) UINT cNames,
        /* [in] */ LCID lcid,
        /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId) = 0;

    virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(
        /* [annotation][in] */
        _In_  DISPID dispIdMember,
        /* [annotation][in] */
        _In_  REFIID riid,
        /* [annotation][in] */
        _In_  LCID lcid,
        /* [annotation][in] */
        _In_  WORD wFlags,
        /* [annotation][out][in] */
        _In_  DISPPARAMS *pDispParams,
        /* [annotation][out] */
        _Out_opt_  VARIANT *pVarResult,
        /* [annotation][out] */
        _Out_opt_  EXCEPINFO *pExcepInfo,
        /* [annotation][out] */
        _Out_opt_  UINT *puArgErr) = 0;

};

Then just include your header in your IDL.
 
Share this answer
 
v2
Comments
Zon-cpp 18-Feb-15 4:39am    
syntax error : expecting { near ","
Vladimir Svyatski 18-Feb-15 5:07am    
It's a limitation of current implementation of MIDL. See the updated solution.
Zon-cpp 18-Feb-15 5:32am    
I added my base class derived from IDispatch, then it have to include the 'oaidl.h'
when I include my base header in IDL, it get this errors:

error MIDL2003: redefinition : INT
error MIDL2003: redefinition : _LARGE_INTEGER
error MIDL2003: redefinition : _ULARGE_INTEGER
error MIDL2003: redefinition : Int64ShllMod32
error MIDL2025: syntax error : expecting ; near "{"
error MIDL2026: cannot recover from earlier syntax errors; aborting compilation

Vladimir Svyatski 18-Feb-15 10:15am    
This may be a stupid question, but do you have the #pragma once directive in the beginning of your header file?
Zon-cpp 18-Feb-15 23:59pm    
Because in IDL import "oaidl.idl" and in my header file include "oaidl.h"
I think they are conflict. But how do i resolve?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900