Reputation: 1360
Having searched for days now i decided to post a question here and hope that somebody has the ultimate idea or advice.
I wrote a WINAPI wrapping mechanism consisting of a WindowManager and a WINAPIWindow class. The latter uses the famous "First WINAPI Window" functionality known from most tutorials in a more structured manner, mainly HWND and HINSTANCE. Remarks: the macro "_ WINDOWS _" (without spaces but this tool makes it bold otherwise ) is a macro defined in one of my headers to determine, wether the compilation environment supports WIN32 and the WINAPI.
#if defined(_ _WINDOWS_ _)
LRESULT CALLBACK gDefaultWndProcFwd(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
#pragma region WINAPIWindow
class WINAPIWindow : public WindowBase
{
friend class WindowManager;
public:
virtual ~WINAPIWindow();
RESULT show();
inline HWND handle() const;
LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
WINAPIWindow(__in const HINSTANCE hInstance, __in const Rect& bounds, __in const String& title = "", __in const int flags = WDF_DEFAULT);
HRESULT createWindowClass(__in const HINSTANCE hInstance, __in const String& clsName);
tInt16 _wndState;
HWND _hWnd;
};
typedef WINAPIWindow Window;
#pragma endregion
#elif
The mechanism is located in a static library called "ShirabePlatformFeatureLayer.lib". This static library uses classes and code from another custom static lib called "ShiCore.lib" which does not use any platform dependent code.
My actual application project (x64!) now imports both as additional depenencies using the WindowManager.
Although both library projects compile fine and without errors, compiling the Application Project leads to the following error messages.
Error 43 error LNK2019: unresolved external symbol "public: struct HWND__ * __cdecl ShirabePlatformFeatureLayer::WINAPIWindow::handle(void)const " (?handle@WINAPIWindow@ShirabePlatformFeatureLayer@@QEBAPEAUHWND__@@XZ) referenced in function wWinMain C:\Users\Dev.Dev-PC\Documents\Workspaces\ShirabeEngine\ShirabeDevelopment\Win32TestProject\main.obj Win32TestProject
Error 45 error LNK2019: unresolved external symbol "__int64 __cdecl ShirabePlatformFeatureLayer::gDefaultWndProcFwd(struct HWND__ *,unsigned int,unsigned __int64,__int64)" (?gDefaultWndProcFwd@ShirabePlatformFeatureLayer@@YA_JPEAUHWND__@@I_K_J@Z) referenced in function "private: long __cdecl ShirabePlatformFeatureLayer::WINAPIWindow::createWindowClass(struct HINSTANCE__ * const,class ShirabeCORE::String const &)" (?createWindowClass@WINAPIWindow@ShirabePlatformFeatureLayer@@AEAAJQEAUHINSTANCE__@@AEBVString@ShirabeCORE@@@Z) C:\Users\Dev.Dev-PC\Documents\Workspaces\ShirabeEngine\ShirabeDevelopment\Win32TestProject\ShirabePlatformFeatureLayer.lib(Window.obj) Win32TestProject
Error 44 error LNK2001: unresolved external symbol "public: struct HWND__ * __cdecl ShirabePlatformFeatureLayer::WINAPIWindow::handle(void)const " (?handle@WINAPIWindow@ShirabePlatformFeatureLayer@@QEBAPEAUHWND__@@XZ) C:\Users\Dev.Dev-PC\Documents\Workspaces\ShirabeEngine\ShirabeDevelopment\Win32TestProject\ShirabePlatformFeatureLayer.lib(WindowManager.obj) Win32TestProject
Error 46 error LNK1120: 2 unresolved externals C:\Users\Dev.Dev-PC\Documents\Workspaces\ShirabeEngine\ShirabeDevelopment\Debug\Win32TestProject.exe Win32TestProject
I checked, whether the methods are declared and defined properly. I also included and imported the libs.
#if defined(_ _WINDOWS_ _)
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "gdi32.lib")
#include <Windows.h>
#endif
In addition i registered the 3 libs above as additional dependencies and the lib-directories are $(VC_LibraryPath_x64) and $(WindowsSDK_LibraryPath_x64).
My first thoughts after having analyzed this a bit is, that all methods or functions that use WINAPI classes and structs are not linked into the import library "ShirabePlatformFeatureLayer.lib". Having registered them above 3 libs as additional dependencies with equal library paths as above and the /VERBOSE:LIB shows me that the libraries are appended but not with "x64\gdi32.lib" as the message but "GDI32.DLL". Likewise for the other two.
Doing /VERBOSE:LIB in the application project shows me the actual relative paths to the "~.lib" and not "~.DLL".
What can cause the methods to not being linked/included/important when they use WINAPI functionality? Is the general build design with so many .libs the problem? Does anybody else have an idea?
Here the entire affected code ( imho ): http://pastebin.com/f7MaBBwM
If any further information is required, please tell me.
EDIT: I've continued searching and came up with the "project to project" dependencies in the new MSBuild system. Although this appeared to be the same problem, it isn't since obviously the dependency of "ShirabePlatformFeatureLayer.lib" to the import libs kernel32, gdi32 and user32 causes problem, when effectively being consumed by the Win32TestProject using the ShirabePlatformFeatureLayer.lib code.
Unfortunately i wasn't able to solve the problem yet with the various advice given est. 10 different articles on the topic. :/
Edit: Consulting Rodrigo s remarks i was able to get rid of the handle() unresolved symbol. However the second with gDefaultWndProcFwd seems to be a logic/design error.
Once i managed to get 10 Reputation I'll attach an image of the relation between WindowManager, WINAPIWindow and gDefaultWndProcFwd! That said here a textual description:
1) Creating the window implies creating the WindowClassEx structure that refers to gDefaultWndProcFwd using a forward declaration in Window.h.
2) When the window is created and shown the method should be called, which consults WIndowManager::get(key : HWND) : WindowBase*;
3) If found, the function invokes wndProc on the window pointer and leaves handling to the specified implementation of the wndproc.
The gDefaultWndProcFwd is declared and defined in WindowManager.h/.cpp.
The design flaw becomes more and more obvious, as I'm thinking about a solution! See the pastebin link for the actual code!
Thank you very much for your help in advance.
Sincerely, Marc
Upvotes: 2
Views: 2061
Reputation: 98486
You have 2 unresolved external symbols:
HWND ShirabePlatformFeatureLayer::WINAPIWindow::handle(void) const
LRESULT ShirabePlatformFeatureLayer::gDefaultWndProcFwd(HWND,UINT,WPARAM,LPARAM)
The first one is probably due to handle()
being inline. You probably defined it in the CPP file (or you forgot it?) , but since it is inline, the definition is not exported. Instead it is expected to be available to every compilation unit that needs it. In other words, inline functions should be defined in the same header file as the declaration.
The second one is trickier without seeing all your code. But I'd bet that you simply forgot to write the defintion of gDefaultWndProcFwd()
. Or maybe you wrote it in a different namespace, or with different parameters.
Note that static libraries are not linked, so unresolved symbol errors such as yours, will never happen when building the library, even when the defect is in the library itself. Linker errors will always happen when linking the final executable.
UPDATE: Ok, I said it was tricky... Re-reading your code I noticed that the offending function is declared twice, and defined once. That itself is not a problem, but look at the two declarations together:
LRESULT CALLBACK gDefaultWndProcFwd(HWND hWnd, UINT msg, LPARAM lParam, WPARAM wParam);
LRESULT CALLBACK gDefaultWndProcFwd(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
And the definition is:
LRESULT CALLBACK gDefaultWndProcFwd(HWND hWnd, UINT msg, LPARAM lParam, WPARAM wParam)
Do you see the difference? WPARAM
and LPARAM
are swapped!!!
Upvotes: 1