Re: Switching between interfaces without knowing derived object.
On Aug 14, 7:25 am, Lars Tetzlaff <lars.tetzl...@gmx.net> wrote:
peter koch schrieb:
On 12 Aug., 23:48, Lars Tetzlaff <lars.tetzl...@gmx.net> wrote:
peter koch schrieb:
On 11 Aug., 20:20, hardy <hardy_hard...@yahoo.co.in> wrote:
Hello
Consider a case in which we have two interface classes I1 and I2 and a
derived Class D implementing both of these interfaces. This is a part
of the library and the library-user does not know the definition of
Class D. It knows only about I1 and I2. API's of this library return
pointers to interfaces, say I1 for this example. So if the user has a
pointer to object of type I1 and wants to convert it to I2*. Is there
a C++ standard way of converting it?
Yes - lookup std::dynamic_cast.
This is a solution, if you not only know about I1 and I2 but also that
the implementation of I1 implements I2, or, in other words, you need
*some* knowledge about Class D.
This is not true. You don't need to know anything at all about D.
/Peter
You have to know that there is a class that implements both interfaces
and that the library implementer wants you to cast I1 to I2. That is
what i meant with "some knowledge". You do not need a header or even the
name of D.
Lars
The gcc version i am using is 4.0.1 on Mandriva Linux release 2006. I
am able to replicate the problem in an isolated source. The problem,
i.e dynamic_cast returns NULL, occurs when the shared library is
linked and loaded at runtime.
g++ -O2 -Wall -o test test.cpp testlib.h -ldl
However when the shared library is passed as -ltest to g++, while
building the user application then the dynamic_cast works as
expected.
g++ -O2 -Wall -o test test.cpp testlib.h -ldl -ltest
(
The library is built as libtest.so
g++ -O2 -Wall -fPIC -c testlib.cpp
g++ -shared -o libtest.so *.o
)
Can someone share some thoughts on why this happens.
Is it possible to make dynamic_cast work in this case, when the shared
library is linked and loaded at runtime? Can we do something
differently in loading the shared library at runtime?
-hardy
Sample Code.
This is testlib.cpp
#include "testlib.h"
class Derived : public Itf1, public Itf2
{
public:
virtual ~Derived(){}
void bar() { cout << "Bar" << endl; }
void foo() { cout << "Foo" << endl; }
};
#ifdef __cplusplus
extern "C" {
#endif
void* GetItf()
{
Derived* d = new Derived();
return static_cast<Itf1*>(d);
}
#ifdef __cplusplus
}
#endif
This is testlib.h
#include <iostream>
using namespace std;
class Itf1 {
public:
virtual ~Itf1() {}
virtual void foo() = 0;
};
class Itf2 {
public:
virtual ~Itf2() {}
virtual void bar() = 0;
};
This is the user application test.cpp
#include <dlfcn.h>
#include "testlib.h"
int main(void)
{
void *lib_handle;
void* (*GetInterfaceFromLib)();
char *error;
lib_handle = dlopen("/pathtolib/libtest.so", RTLD_LAZY);
if (!lib_handle)
{
cout << dlerror() << endl;
exit(1);
}
GetInterfaceFromLib = (void*(*)())dlsym(lib_handle, "GetItf");
if ((error = dlerror()) != NULL)
{
cout << error << endl;
exit(1);
}
Itf1* p = NULL;
void** pvoid = (void**)(&p);
*pvoid = (*GetInterfaceFromLib)();
p->foo();
Itf2* p2 = dynamic_cast<Itf2*>(p);
if(p2)
p2->bar();
delete p;
dlclose(lib_handle);
return 0;
}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]