views:

578

answers:

4

First off , I'm referring to a Windows environment and VC++ compiler.

What I want to be able to do is rebuild a Vc++ dll and maintain compatability with an exe that has already been linked to the lib without having to rebuild the exe or load the dll dynamically using LoadLibrary. In other words, is there a way to add classes and methods to a dll(but not remove any) and ensure the existing entrypoints remain the same?

A: 

As long as you don't add any exported symbols, the ordinals won't change. If you add exported symbols through the standard dllexport mechanism, then that's going to be difficult to control. If you use the old style .xpf symbol file you might be able to control the ordering of the symbols in the lib (although I don't know this for sure - it might still reorder them however it likes), but it's tricky to do C++ symbols this way.

Nick Bastin
+4  A: 

If you export the functions from using a DEF file and manually specify the ordinals, you should be able to accomplish this.

Reference

http://msdn.microsoft.com/en-us/library/d91k01sh(VS.80).aspx

Michael McCloskey
I'd like to add the reference http://msdn.microsoft.com/en-us/library/900axts6(VS.80).aspxIt's just one click away from the above hyperlink and discusses the reasons for using def files and the pros and cons.
Rich
A: 

I think that ordinals are rarely used to resolve DLL imports anymore - I think that you have to use .def files to get the linker to use them. So as long as you don't change names or signatures of the exported functions, the .exe should work just fine.

Michael Burr
+5  A: 

It depends on how your EXE used the classes from the DLL. Adding new classes should not affect existing entrypoints. Aside from that, however, any the following will affect object size and/or layout, and as such will be a client-breaking change (note that this is technically VC-specific, but most of these apply to any sane implementation):

  • Removing fields (even private) from classes
  • Adding new fields (even private) to classes
  • Adding new base classes to existing classes
  • Removing base classes from existing classes
  • Adding new virtual method before an existing virtual method (adding new virtual methods after existing ones is okay, except for the case described in next point)
  • Adding a new virtual method in a class that is used as base class by another class in the same DLL which also has virtual methods
  • Changing type of existing fields
  • Changing signature of existing methods
  • Making a virtual method non-virtual, and vice versa
Pavel Minaev
I think this is a good answer, but I'd change one thing: changing the virtual methods in a class in any way would be suspect. I don't think you can count on the vtable to have the virtual functions in that same order as they show in the source file.
Michael Burr
In VC at least, you can count on that - this is prerequisite for COM support (which requires definite vtable ordering).
Pavel Minaev
Great answer Pavel, I just wonder if you could add some references in order to support your assertions. Thank you!
David Alfonso
@David, it's mostly knowledge coming out of 1) understanding of typical implementation techniques (vtables etc), and 2) experience. The primary source here would be ABI specification for a particular compiler. Looking at secondary sources, KDE docs have a list similar to mine here: http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++ - and generally searching for "C++ binary compatibility" should give a few more relevant hits.
Pavel Minaev