There are two projects. One is called VampEngine (a Shared Library) and the other Application (A console application).
The VampEngine contains a VampEngine::Core class. This function contains a void VampEngine::Core::MainLoop() method.
There are also two extern C functions void *Vamp_Core_Constructor() and Vamp_Core_MainLoop(void *obj)
Now, this is what happens:
The client is calling void *Vamp_Core_Constructor() in order to create a VampEngine::Core which lives inside the Shared Library. And also casts this void object into a Core object.
The void VampEngine::Core::MainLoop() is being implemented both in the Shared Library and in the client. The client's MainLoop() is just a wrapper for calling the extern c function Vamp_Core_MainLoop(void *obj)
The code compiles and links in both Windows and Linux. When you run it on Windows, MainLoop() (shared library's implementation) is getting called, but on Linux, there is a recursive call in the client's MainLoop() implementation.
The behavior in each Operating System can be shown below:
You can check the project (It's small, I just started it ) On my GitHub Repo . Also, I have a Premake script if you want to check the code for yourself. You are most interested in the files:
API.h EntryPoint.h Application.hpp Core.cpp Core.h Core.hpp Main.cpp
This might explain the problem in a better way:
The Core class has two implementations of the Core::MainLoop(). One is implemented inside the DLL and the other in the client. The client's implementation is just a wrapper which calls a c extern function (which lives in the dll) which actually calls the MainLoop() implemented inside the DLL.
Now in visual c++, because I'm only exporting that c extern function, Core::MainLoop() acts in a polymorphic way. The client calls his implementation of Core::MainLoop() which calls the extern function and eventually the Core::MainLoop() inside the dll runs.
On linux, I believe by default all the symbols are getting exported. And this is the behavior I saw using a debugger:
The client calls Core::MainLoop() , this calls the extern function, the extern function calls again Core::MainLoop() but instead of running the dll implementation it actually runs the the clients implementation. It's like the clients Core::MainLoop() is calling itself over and over again!
Conclusion:
I located the above behavior using gdb debugger on Linux. I just noticed the client's implementation was getting called in a recursive way instead of acting polymorphically ending up calling the implementation of the dll's MainLoop()