Multiple Layers of inheritance II

Kamran

New member
Joined
May 29, 2013
Messages
22
Reaction score
0
Points
0
I'm trying to do the same thing as Hlynkacg did in his thread titled "Multiple Layers of inheritance" see here where HLynkacg created a class that inherited from the VESSEL3. He then created another class that inherited from that class.
Face noted (towards the end of page 2) that his implimentation for his base class was held in a different dll than his child class. Then I think that HLynkacg put all his classes together into 1 dll and everything worked fine.

I can't do that, because I want our orbiter community to be able to add their own buildings as they wish by inheriting off the building class which itself is derived from the VESSEL3 class. If I were to consolidate all the classes into one dll then no one will be able to add building of their own.

I'm getting the same output error messages upon compillation as HLynkacg got...

HTML:
1>SMC_HQ.obj : error LNK2019: unresolved external symbol "public: __thiscall Building::~Building(void)" (??1Building@@QAE@XZ) referenced in function "public: __thiscall SMC_HQ::~SMC_HQ(void)" (??1SMC_HQ@@QAE@XZ)
1>SMC_HQ.obj : error LNK2019: unresolved external symbol "public: __thiscall Building::Building(void *,int)" (??0Building@@QAE@PAXH@Z) referenced in function "public: __thiscall SMC_HQ::SMC_HQ(void *,int)" (??0SMC_HQ@@QAE@PAXH@Z

...where Building is my parent class, and SMC_HQ is my child class. Both are held in separate .dlls. Both of these error messages are in relation to constructor/destructor methods defined in both Building and SMC_HQ .h files.

I am sure this can be done, otherwise noone would be able to inherit the VESSEL3 class, would they?
 
Last edited:
Did you include or generate an interface.lib to dynamically bind your program to that DLL that way?
 
No :huh:
I've got no idea how to do that, could you briefly explain how this can be done, or where I may get the information to learn?
 
No :huh:
I've got no idea how to do that, could you briefly explain how this can be done, or where I may get the information to learn?

if you create a DLL, you should also get a .lib produced by the linker. This .lib contains the program code needed to access the functions in your DLL.
 
Should I throw this into my lib folder?

If you have one. Maybe. Don't know your project structure or which compiler version you use.
 
I have the usual orbiter addon setup by following instructions made by Mohd Ali in his video here. I'm using Visual Studio 2010 Ultimate with the standard C++ Import/Export Settings.

This setup does connect the compiler to access .lib files from the lib directory in Orbitersdk/lib directory.

I've thought of jumping the gun and threw my .lib file found in my debug folder to the orbitersdk/lib folder. Compiled with same error message.
 
Have you told the compiler to use the library, for example by adding it as existing item in your project?
 
Yea, I've tried that. Still no luck :(

Then I am also still out of luck... can you post the compiler and linker command lines, as VS displays them, between code tags here?

Maybe we missed something crucial.
 
Sometimes I need to add the lib explicitly to "additional dependencies", although the lib directory is already declared. I'm not sure why, really, but maybe it helps.



Although I had a similar problem with another thingy I was working on. the third party library came with a dll, a lib and source code.

When I adapted the source, I had to build the dll and the lib again, of course. I built as dll, took the new lib and the new dll and put them in the appropriate folders. But the code that used the lib would not build against the new lib. Instead, I had to build the library as a static lib, then take that lib, and it built. For some reason, the lib outputed as a "by-product" of the dll didn't work, while a purpose built lib did.

Of course, upon bulding against the lib, the program didn't reference the DLL anymore, as can be expected, so that probably won't work for an orbiter add-on... :shifty:
 
Sometimes I need to add the lib explicitly to "additional dependencies", although the lib directory is already declared. I'm not sure why, really, but maybe it helps.

That is actually the normal behavior, since the lib directly only declares, where to look for the requested libraries. It does not say, which library is needed from those in the library (can be many) or which version of the library is needed (can be many versions).

You can add also libraries to your project in VC++ as existing item (add -> Existing Item), it then also handles them correctly, that is the way that I prefer currently.
 
I found that I need to add both the .lib and .obj files to remove the LNK 2019 error. But I now get another error...
HTML:
1>SolarMiningCo.obj : error LNK2005: "void __cdecl calldummy(void)" (?calldummy@@YAXXZ) already defined in SMC_HQ.obj
1>SolarMiningCo.obj : error LNK2005: _ModuleDate already defined in SMC_HQ.obj
...I've tried calling every dummy that I know off but, they don't know what I'm talking about. :P

I've read a little about what this error message means, but I am not responsible for the creation of a "calldummy" or "ModuleDate" method and so cannot alter it definition. Also upon double clicking on the error message to tell me where it found it, VS tells me that it can't locate the file. I think the file may be the .obj that I included into the project to remove the LNK 2019 error message.
Could my new .obj file be duplicating this method?
 
Last edited:
Perhaps this read is a good start on the topic of exporting C++ classes: http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL

I admit that I never tried such a constellation (DLL A implements class X, DLL B implements class Y deriving from X, Y gets instanced in Orbiter) myself with C++ in Orbiter, but with .NET in Orbiter. With the later the binding was a bit tricky due to the locations the implicit DLL gets loaded from. I suspect the same might be true for pure C++ implementations.

I'd suggest to start with a minimal test setup first:

  1. get a clean Orbiter install,
  2. implement a (simple) VESSEL3 derived class X in DLL A,
  3. also create a config file for X, so you can test it in Orbiter,
  4. dllexport class X in A, recompile for .lib file,
  5. create DLL B with import of A.lib file,
  6. dllimport class X through shared header file,
  7. implement an X derived class Y in DLL B,
  8. create config file for Y, test in Orbiter.
Unfortunately, though, I think this is not a trivial thing to do, so be aware of all kinds of pitfalls and DLL-hell.

hope this helps,
Face

EDIT: Please work your project in a public repository somewhere, at least for the test setup. This way, the rest of the community can see how it works out, AND it will be much easier for us to discuss things if the full code and solution is openly reviewable. IMHO, guessing on snippets and prose is getting tiresome really quick if it comes to more involved coding problems.
 
Last edited:
I currently have a number of vessels based on the same common library... but its too early to use a DLL there, since the interfaces are subject to change pretty often.
 
:hesaid:

In one of my modules, I had the exact same errors show up.
I had one class that needed an MFC function (afxwin.h), and several other classes that used pure windows functions (windows.h). afxwin has to be #included before windows.h, but I could not get afxwin included before windows due to my inheritance scheme.

In this case, I split the MFC code into its own static library, and included the library into the main Orbiter module.

When I had ORBITER_MODULE defined in the static library, the linking errors showed up, as ORBITER_MODULE was defined in both the static library and in DLL. You'll have to refactor so ORBITER_MODULE only appears in one of them.

tl;dr: Only #define ORBITER_MODULE once.

---------- Post added at 03:45 PM ---------- Previous post was at 03:43 PM ----------

100th post! :hailprobe:
 
I may have found the answer.

I went back to my exportable class and prefixed my class name with __declspec(dllexport) in the h file, so now it looks like this...
Code:
class [COLOR="RoyalBlue"]__declspec(dllexport)[/COLOR] Building: public VESSEL3{
... compiled it, went to my project that wants to inherit from this .dll removed all the old stuff and imported the .h file and the .lib file from my exportable class. Compiled. Success! :headbang:

Mind you, this class only contains a constructor and destructor, nothing else. But I'm hopeful that I've seen the end of my problems with this matter. :rofl:

Thanks Face for guiding me to "The Code Project", an awesome website, full of programming knowledge.
And thanks to all of you that have helped me with this problem, I really am grateful for your time and effort. :cheers:
If you'd like more details for the fix of this issue, send me a private pm through this website, or ask me on this thread.
 
Back
Top