explicitly loaded dlls, virtual functions and templates :(

  • Thread starter Thread starter Vyacheslav Lanovets
  • Start date Start date
V

Vyacheslav Lanovets

Hello, All!

One of our target platforms has only 32 MB of virtual memory (Windows CE),
so we decided to explicitly load some of our dlls.

But the classes created inside such dlls are created with vfptr pointed to
address space of the dll. So when DLL is unloaded vtable is destroyed.

The virtual clone() function of such instance creates the class with the
same vfptr :)

The problem could be solved by moving inline functions to cpp files. But the
class is a template :(



Best regards, Vyacheslav Lanovets
 
Maybe I am misunderstanding your point. But if you want to execute code,
this code must be loaded. Instantiating a class and then unloading the DLL
that implements the class must fail obviously.
 
Hello, Marcus!
You wrote on Wed, 10 Aug 2005 22:09:46 +0200:

MH> Maybe I am misunderstanding your point. But if you want to execute
MH> code, this code must be loaded. Instantiating a class and then
MH> unloading the DLL that implements the class must fail obviously.

Yes, but it's such a pity that it's so hard to mix templates, virtual
functions and explicit loading :(

We had to derive from these templates and put constructos into a dll which
is not unloaded.

Best regards, Vyacheslav Lanovets
 
I assume I am still missing something here:

<Vyacheslav>
The problem could be solved by moving inline functions to cpp files. But the
class is a template :(
</Vyacheslav>

Why would the problem be solved by moving inline functions to cpp files?
 
Hello, Marcus!
You wrote on Thu, 11 Aug 2005 17:44:33 +0200:

MH> I assume I am still missing something here:

MH> <Vyacheslav>
MH> The problem could be solved by moving inline functions to cpp files.
MH> But the class is a template :(
MH> </Vyacheslav>

MH> Why would the problem be solved by moving inline functions to cpp
MH> files?

Because classes with inline constructor (or class templates) have
_different_ vtables when created in different DLLs.

When the class template with virtual function clone is created by code in
module A, it's vtable is in module A address space because its
constructor is "inline".
So, when it's constructed in module B, vtable is in module B address space.

The problem is that even if I call ->clone() from module B, I still get a
copy with vtable residing in module A, so I can not use Prototype design
pattern if I want to unload module A.

But as soon as I define constructor in x.cpp, the vtable is placed in module
with x.pp, not in module A or B.

The problem is that this limits usability of templates: in my case I had to
derive all required "instantiations" from class template and declare
constructors of derived classes __declspec(dllexport).

Best regards,
Vyacheslav Lanovets
 
Interesting issue; haven't thought of that so far.

Is your clone method virtual or not?

Marcus
 
Because classes with inline constructor (or class templates) have
_different_ vtables when created in different DLLs.

When the class template with virtual function clone is created by code in
module A, it's vtable is in module A address space because its
constructor is "inline".
So, when it's constructed in module B, vtable is in module B address space.

The problem is that even if I call ->clone() from module B, I still get a
copy with vtable residing in module A, so I can not use Prototype design
pattern if I want to unload module A.

But as soon as I define constructor in x.cpp, the vtable is placed in module
with x.pp, not in module A or B.

The problem is that this limits usability of templates: in my case I had to
derive all required "instantiations" from class template and declare
constructors of derived classes __declspec(dllexport).

Did you try explicitly instantiating and exporting the class template
specializations you're using? That may allow you to control the placement
of the vtbl.

That said, for DLLs I want to dynamically load and unload, I really tend to
favor a purely C-level interface and black box design, in which the DLL
shares no CRT-level state with the EXE or other DLLs. It's hard enough to
make implicit DLL linking work mostly right for C++ code that's supposed to
behave the same as it would under static linking, without worrying about
DLLs coming and going...
 
Hello, Doug!
You wrote on Fri, 12 Aug 2005 10:29:09 -0500:

DHM> Did you try explicitly instantiating and exporting the class template
DHM> specializations you're using? That may allow you to control the
DHM> placement of the vtbl.

Yes, it should work, and it's actually been done in other parts of our code,
but only now I could understand - why :)

But dll import/export symbol tables become too large if the entire class is
exported, and it works now, so I'll better leave it as it is.

DHM> That said, for DLLs I want to dynamically load and unload, I really
DHM> tend to favor a purely C-level interface and black box design, in
DHM> which the DLL shares no CRT-level state with the EXE or other DLLs.

Yes, I absolutely agree. But we did not expect to unload those DLLs.
Implicitly loaded they worked fine even with C++ exported classes, templates
and so on.
But we hit 32MB virtual memory limit of Windows CE :(

And, to say you the truth, I'm really surprised that it was so easy to
convert to explicit loading.

Best regards,
Vyacheslav Lanovets
 
Back
Top