Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Dll with Visual C++ (inheritance)

Status
Not open for further replies.

moiss

Programmer
Jun 25, 2002
7
0
0
VE
Hi,

I am trying to develop a dll with visual c++. This dll provides 2 classes, A and B (and their interfaces iA and iB).
I want that B inherits of A (the full class, not only the interface).
How should i do?
Thanks
Moiss
 
I'm assuming you are talking about a straight dll, not a COM-object.

----------------------------

I thought dlls were only for exporting (C-Style) functions, not C++ classes. But... I found that you apparently can.

There's a very concise tutorial at
look at "Making Class Accessible from a DLL"

you have to register to see the tutorial but it's free and took me two seconds.

I don't know about the inheritance part though, you will have to test that out yourself.

-good luck
 
hi,

thanks for the answer. Yes, i am developping a COM-object, using ATL...
and my problem is about the inheritance i explained...
do you know more about it?
 
Oh...

Well you could try creating two atl objects, A and B, where A is aggregated inside B. I haven't really worked with aggregation much so I don't want to say anymore but check it out.

From another angle: since B inherits "completely" from A you could just make one ATL object with two interfaces:
1. make an ATL object and add all the A functions to the object's interface.
2. manually add a second interface to the object and add all the B functions to that.
3. implement all the functions.

for how to add new interfaces to an existing ATL object look at this page under "Adding Second and Third Interfaces":


there's probably other ways too...

hope this helps
 
Hi,

well, thanks you...
I ve tried to make B inherit from A with the "classical method", i mean in the idl file, we have iA:iDispatch (iA inherits from iDispatch) and iB:iDispatch (making iB inherit from iA but the result was that i just had an inheritance between iB and iA and for example the B class didnt have access to the private A functions).
Then, I understood that I really need to have an inheritance between A and B directly (and not between their interfaces, what will be automatic then).
The code automaticly generated in the B.h file (actually, my class is called CB) is:

class ATL_NO_VTABLE CB :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CB, &CLSID_B>,
public IDispatchImpl<IB, &IID_IB, &LIBID_TEST16Lib>

and with what i added:
class ATL_NO_VTABLE CB :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CB, &CLSID_B>,
public IDispatchImpl<IB, &IID_IB, &LIBID_TEST16Lib>,
public CComCoClass<CB, &CLSID_B>,
public CComCoClass<CA, &CLSID_A>

well, i probably have to add a line, here, in the code below:
BEGIN_COM_MAP(CVehiculo)
COM_INTERFACE_ENTRY(IVehiculo)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
but i don t know what.. i ve all tried I think and I get error every time...
If someone can help me...
Thanks

 
I think COM objects are intended to be instantiated and used through the COM library calls and according to COM rules. You are probably going to see conflicts if you try to just casually inherit B from A because of all the COM overhead. I really don't know enough about ATL/COM to say for sure, but that's my guess. (Please correct me if I'm wrong).

Also, if you could just do inheritance like that why would they have bothered with all the aggregation and assignment/delegation stuff?

What are you intending to do with A and B from the client that makes the inheritance so important?
 
To answer your question, I am developping the numeric part of a big project, which respects the CAPE OPEN norm. This norm let me few liberty and I MUST develop a Matrix Class with such an inheritance :eek:)
Thank you for your help, I will follow investigating :eek:)
 
Sounds cool.

I asked a coworker who works a lot more with COM than me and they'd never heard of doing this kind of inheritance.
They suggested you might have two classes A and B from which the implementation objects derive:

i.e.
do all you implementations here:
class A
class B : public A

class CObjA : public A
class CObjB : public B

Problem is that the inheritance on the client end would probably cause problems. i.e. typical polymorphism like:

B* pB = new A();

since this operation is never done directly (because it's buried in CComClassFactory or some place).

Well that's about as far as I can help, good luck.
-Will Duty
 
Hi,

I didn t understand very well your answer.
I mean, if you use the ATL classes with Visual C++, when you insert a new ATL object, there are automatily 2 files created, for example A.h and A.cpp and the idl file now belong some lines of code which say that the interface of A inherits of IDispatch.
As i said it in my last message, the definition of the A class is:
class ATL_NO_VTABLE CA :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CA, &CLSID_A>,
public IDispatchImpl<IA, &IID_IA, &LIBID_TEST16Lib>

Do you coworker understand my problem? Could they help me?

 
The coworker is very grouchy and says they are too busy. Sorry.

The interface of A and B inherit from IDispatch because you selected &quot;dual&quot; instead of &quot;custom&quot; interface support.
Otherwise you would have inherited from IUnknown (IDispatch inherits from IUnknown anyways). Either way your interfaces must from IUnknown because they are com interfaces.

But there will be conflicts with the class factories. These are not ordinary C++ objects. When you set up a COM object using ATL, the object inherits from its interface (which inherits from IUnknown) but it also inherits from several templates which take care of a various things COM objects have to do (like threading, object creation, etc). One of those is the CComCoClass which sets up the ClassFactory object for the actual object. This object is created by the COM libraries when you instantiate the main object (with CoCreateInstance usually). Since you are trying to create an object with two CComCoClass parameters (class CA and class CB) there will be an ambiguity problem. This is not even dealing with the interface inheritance problem yet.

For a tutorial dealing with interface inheritance look at:

But here you will see that there only one object not two interfaces and two objects.

You still haven't explained why the inheritance structure needs to be this way from a client standpoint. What I mean is can you give an specific example of how the client will deal with objects A and B from the inheritance point of view?

because you don't get direct object pointers when you create com objects, you get interface pointers and from that point of view, why does it matter that CB inherits from CA. Nobody can talk to the objects at that level anyways.
 
Hi,

thank you for so many details,..
yes, apparently, the main problem was that my classes inherited from IDispatch and for this reason, the COM object were badly initialized. I built a new test project and i changed this: i put &quot;custom&quot; instead of &quot;dual&quot;.
But i still have problems.
My 2 classes are CContainer and CGlace.
I create them(the both checking &quot;dual&quot;), I write the &quot;public IContainer&quot; in the glace.h file (to make the inheritance between the 2 classes) and until this point, it does compile without errors. But when I add a Method in the mother class (CContainer) using the ATL Object Add interface (right click on the ATL object with VC++), then it doesn't compile anymore, and i get this error:
&quot;error C2259: 'CComObject<class CGlace>' : cannot instantiate abstract class due to following members:
c:\program files\microsoft visual studio\vc98\atl\include\atlcom.h(1823) : while compiling class-template member function 'long __stdcall ATL::CComCreator<class ATL::CComObject<class CGlace> >::CreateInstance(void *,const struct _GUID &,void
** )&quot;

and the following warning:
&quot;c:\program files\microsoft visual studio\vc98\atl\include\atlcom.h(1827) : warning C4259: 'long __stdcall IContainer::FillUp(int *)' : pure virtual function was not defined
d:\sebastien\solver\test\test19\test19.h(98) : see declaration of FillUp
c:\program files\microsoft visual studio\vc98\atl\include\atlcom.h(1823) : while compiling class-template member function 'long __stdcall ATL::CComCreator<class ATL::CComObject<class CGlace> >::CreateInstance(void *,const struct _GUID &,void
** )'&quot;
Can you help me?

To answer your question, I thought that i need to have an inheritance between CContainer and CGlace directly because, i ll need to use the same no-exported methods in the both classes: for example, i have a protected function X() in the both classes that i don t wanna export... but, it s not a problem at all, i ll copy and paste it.
 
hmm...
But you are still going to have problems because you are trying to have one object inherit the interface for another object. I'm not sure this will work. One way I think you could proceed is:
1. create one ATL object (A)
2. add all your A methods to its interface IA
3. Instead of creating a second object, add a second interface (IB) to the A object and have it inherit from IA.
4. implement all the methods for both interfaces in your object.
To add the second interface look at the link I put above in the second response.


the other way you could do it is to have your two objects (&quot;glace&quot; and &quot;container&quot;) and two ATL objects which inherit from those, then have forwarding calls to the methods:

// A.h
// REGULAR C++ OBJECT
class baseA
{
public:
void AObjectMethod();
};

// COM OBJECT
class ATL_NO_VTABLE CA :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CA, &CLSID_A>,
public IA,
public baseA



//B.h
// REGULAR C++ OBJECT
class baseB : public baseA
{
};

// COM OBJECT
class ATL_NO_VTABLE CB :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CB, &CLSID_B>,
public IB,
public baseB
{

this approach compiles for me and I can call AMethod() in CB:

STDMETHODIMP CB::Bmethod1()
{
// TODO: Add your implementation code here
this->Amethod();
return S_OK;
}

now you can use the method &quot;AObjectMethod()&quot; in CB with no problem because CB inherits from baseB which inherits from baseA. But you now need to add methods to each interface which forward the calls to the master classes. So for IA you need to add an interface method like:

STDMETHOD(forwardAMethod)()

STDMETHODIMP CB::forwardAMethod()
{
AMethod();
return S_OK;
}

and &quot;forwardAMethod&quot; is what clients would call. In this way your existing code can be used as is without trying to force it into a com structure.

But you will have to also fiddle around with parameters and function signatures - if you have a method like

BOOL getVal(int val);

In baseA, it will have to become something like:

STDMETHODIMP CB::forwardgetVal(BOOL* b, int val)

in the CA forwarding call.






 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top