i’m using VS2010, and i am designing a MVC application.
Say i have “Project 1” and “Project 2” in a solution. The need to be compiled in that order, P1 compiles to a DLL, P2 to an Exe file that dynamically uses the DLL. P2 declares a view interface. Both projects have a view class that implements the interface (a class with pure virtual methods).
The problem now is, that i cannot include the header file of the interface in P1, because the linker would say then that he cannot resolve this external symbol. Which is of course right, because it is compiled later in P2.
So what i did is, i added the include folder for P2 to P1 and included the interface.cpp in P1 instead of the header file.
It works, but i don’t think this is what i am supposed to do. Or isn’t it? The interface is obviously compiled twice, once in each project.
I don’t want to move the interface to P1, what would solve the problem. Just assume, i don’t want that.
Thanks for input.
edit: code snippet:
Project1:
View1.hpp // nothing special
View1.cpp:
#include ViewInterface.cpp
View1::View1(int x) : ViewInterface(int x)
Project2:
ViewInterface.hpp:
#ifdef EXP
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif
class ViewInterface : SomeOtherClass, AnotherClass
{
virtual void DECLDIR show(void) const = 0;
virtual void DECLDIR hide(void) const = 0;
}
ViewInterface.cpp:
ViewInterface::ViewInterface(int x) : SomeOtherClass(int x), AnotherClass(int x)
View2.hpp // nothing special
View2.cpp:
#define EXP
#include ViewInterface.h
View2::View2(int x) : ViewInterface(int x)
Then move it to a third entity.
You have to decide what’s more important to you. If you want a clean solution, then either move the interface definition to the DLL (P1), or to something that both the DLL and the EXE can use – let’s call it “P0”. P0 doesn’t even have to be something that’s compiled – a simple header file in it’s own directory with everything defined inline will do just fine. My preferred choice would be to have P0 be a DLL though.
That is the only clean solution. The following “solutions” are really just hacks that I describe for sake of completeness.
If you really want the “dirty” solution, then do the same, with the only difference that you leave the header file defining the interface in the application-source-folder.
And if you want it ultra-dirty, then include the .cpp file when building the DLL like you suggested. It will also work… it’s just really yuck.
Of course you do have to be aware of some things. E.g. the “interface” should not have any static data members, and no function in the “interface” should have function local statics. Because if they do, then those static variables will be instantiated twice – once in the DLL and once in the EXE. Also since all code will be compiled into both projects, you have to re-compile both projects if you want to change anything. (The code being duplicated in the DLL and EXE isn’t a problem as long as they were compiled from the same code.)
Those limitations of course also apply if you choose the “P0 = just a header file” solution.
And finally there’s the really really bad super-dirty solution: implement the interface in the EXE, dllexport it from the EXE and dllimport it in the DLL (yes, that can be done!). Downside is that you would have to do a special EXE build that only builds the import-library for the EXE (which can be done without having the import library for the DLL). With the import library for the EXE you can then build the DLL, and with the import library for the DLL you can then build the EXE itself.
That way the “interface” could even have static data members, and if you change only the code (i.e. no changes in the header-files) then you would only have to re-compile the EXE.