Causes of linker error in Windows mode and no error in Linux environment in Oment++ 6.0.2 for same project

44 Views Asked by At

I built my project on windows 11 with the mingwenv tool available in the Omnet++ 6.0.2 but linker error occurs. I built the same project with the Omnet++ 6.0.2 on the Ubuntu version 22 platform, but the same project was built without any errors. Why does this error occur for Windows mode and how can this problem be solved? Part of the linker error is as follows:

>>>               out/clang-debug//source/routing/myAodvRouteData.o:(myaodv::myAodvRouteData::~myAodvRouteData())

ld.lld: error: undefined symbol: __declspec(dllimport) vtable for myaodv::myAodvControlPacketsSerializer
>>> referenced by source/routing/myAodvControlPacketsSerializer.h:26
>>>               out/clang-debug//source/routing/myAodvControlPacketsSerializer.o:(myaodv::myAodvControlPacketsSerializer::myAodvControlPacketsSerializer())
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:104: out/clang-debug//myAODV_dbg.exe] Error 1
"make MODE=debug all" terminated with exit code 2. Build might be incomplete.
1

There are 1 best solutions below

0
Rudi On

Linking with dynamic libraries (DLLs) are a LOT trickier on Windows than on Linux.

On Linux, you just build your shared library first, then use the header file in an other project and link against that library and the Linux dynamic linker will just link together the two binaries without any user help.

Windows is working differently. To be able to link two binaries dynamically, special code must be used both at the caller and the callee site, that must be generated DURING the compile phase. It means that different code must be generated from the same class/method declaration depending whether it is used inside the .DLL file or the calle (.EXE file). In one case you must add __declspec(dllexport) in the other case __declspec(dllimport). This can be done only by defining various macros that expand to either of these depending on the usage.

Check how the INET_API macro works in INET (in INETDefs.h), and you must implement a similar approach for your own project (with your own macro name) and then pass the required defines from compiler command line depending on whether you are building the DLL (XXX_EXPORT) or using (XXX_IMPORT) it. In INET is looks like this:

#if defined(INET_EXPORT)
#define INET_API          OPP_DLLEXPORT
#elif defined(INET_IMPORT)
#define INET_API          OPP_DLLIMPORT
#else // if defined(INET_EXPORT)
#define INET_API
#endif // if defined(INET_EXPORT)

all class declarations are annotated:

class INET_API MyClassInINET { ... }

and you pass to the compiler -DINET_EXPORT when you build INET and -DINET_IMPORT when you are using INET from a 3rd party project.

I know... It looks confusing and complex, because it is...