W3C home > Mailing lists > Public > www-lib@w3.org > January to March 2002

Problem about Object Inheritance through several dll

From: William BERGES <William.BERGES@gemplus.com>
Date: Thu, 10 Jan 2002 09:27:07 -0500 (EST)
To: <www-lib@w3.org>
Message-Id: <004f01c199e2$e0e1d640$f316020a@wberges.gsw.gemplus.com>
Context : Visual C++ (6)
Object : Object Inheritance through several dll

Hello vrybody,

I have a problem concerning C++ derivation using imbricated dlls.
I would like to use in a main program some methods provided by a base class
and its derived class.

CDerivedClass derivedClass;
int result = derivedClass.GetDerivedNumber(); // Provided by the derived
class : DLL2
result = derivedClass.GetBaseNumber();    // Provided by the base class :
DLL1

The base class is in a dll, the derived class in another one.
 EXE => DLL2 (derived) => DLL1 (base)
A link error appears when a try to call a method provided by the base class
:

Creating library Debug/testdll.lib and object Debug/testdll.exp
testdll.obj : error LNK2001: unresolved external symbol "public: int
__thiscall CBaseDll::GetBaseNumber(void)" (?GetBaseNumber@CBaseDll@@QAEHXZ)
Debug/testdll.exe : fatal error LNK1120: 1 unresolved external

It seems that declare the derived class as export is not enough to export
the base class in the same time.
By using macros in the base header (DLLBASE_EXPORTS), I have declared the
base class as export in DLL1, import in DLL2.
But to be able to use base methods in my EXE, the base class should be
declared as EXPORT in DLL2 too.

I have found 3 different solutions which work but which doesn't satisfy
myself :

1. I have added a .DEF in my DLL2 project (derived class). In this DEF file,
I have explicitely exported the base class method(s).

EXPORTS
 ?GetBaseNumber@CBaseClass@@QAEHXZ

=> Problem : bad lisibility, bad maintenance (parameter added or removed =>
change method signature)...

2. I have added the basical dll LIB (DLL1.LIB) to the main project. => EXE
is linked with both DLL1.LIB & DLL2.LIB
=> Problem : the end user should only know that it uses a class provided by
a dll (DLL2) and derived from a base class,
but it shouldn't know that the base class is inside an external dll (DLL1).
The EXE should only have a focus on the derived class and its container,
DLL2.
It's more visible when DLL2 library is dynamically loaded ; the user
shouldn't have to be linked with a DLL.

3. Redefine all base methods in my derived class (delegation)

class (dllexport) MyDerivedClass : public MyBaseClass
{
    // Local methods
    .....
    // Redefine base class methods
    void myBaseMethod()
    {
        MyBaseClass::myBaseMethod();
    }
}
=> Problem : I have to redefine all base functions... not very nice...
tedious.

My question : how may I resolve my problem without using my solutions ?
If using a DEF file is OK, how may I do the same thing using only dllexport
& dllimport combinations ???

Example files are given below.

@@@@@@@@@@@@@
Thanks for your help.
William.
@@@@@@@@@@@@@

EXE = Main project
------------
Main
{
 CDerivedClass derivedClass;
 int result = derivedClass.GetDerivedNumber(); // Provided by the derived
class : DLL2
 result = derivedClass.GetBaseNumber();    // Provided by the base class :
DLL1
}

DLL1 = Base class project :
=================
H :
---
#ifdef DLLBASE_EXPORTS
#define DLLBASE_API __declspec(dllexport)
#else
#define DLLBASE_API __declspec(dllimport)
#endif

class DLLBASE_API CBaseClass
{
public:
 CBaseClass(void);

 int GetBaseNumber();
};

CPP :
----
int CBaseClass::GetBaseNumber()
{
 return 10;
}

DLL2 = Derived class project :
====================
H :
---
#include "../dllbase/dllbase.h"

#ifdef DERIVEDDLL_EXPORTS
#define DERIVEDDLL_API __declspec(dllexport)
#else
#define DERIVEDDLL_API __declspec(dllimport)
#endif

class DERIVEDDLL_API CDerivedClass : public CBaseClass
{
public:
 CDerivedClass(void);
 int GetDerivedNumber();
};

CPP :
----
int CDerivedClass::GetDerivedNumber()
{
 return  GetBaseNumber()*2;
}





Received on Thursday, 10 January 2002 09:40:54 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 23 April 2007 18:18:40 GMT