现在搜索了几天我决定在这里发一个问题,并希望有人有最终的想法或建议。
我编写了一个由WindowManager和WINAPIWindow类组成的WINAPI包装机制。后者使用着名的“第一个WINAPI窗口”功能,大多数教程都以更结构化的方式,主要是HWND和HINSTANCE。 备注:宏“_ WINDOWS _”(没有空格,但这个工具使其粗体,否则)是在我的一个标题中定义的宏来确定,编译环境是否支持WIN32和WINAPI。 / p>
#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
该机制位于名为“ShirabePlatformFeatureLayer.lib”的静态库中。 这个静态库使用另一个名为“ShiCore.lib”的自定义静态库中的类和代码,它不使用任何平台相关代码。
我的实际应用程序项目(x64!)现在使用WindowManager作为附加的附加项导入。
尽管两个库项目编译良好且没有错误,但编译Application Project会导致以下错误消息。
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
我检查了方法是否被正确声明和定义。我还包括并导入了lib。
#if defined(_ _WINDOWS_ _)
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "gdi32.lib")
#include <Windows.h>
#endif
另外,我在上面注册了3个lib作为附加依赖项,lib目录是$(VC_LibraryPath_x64)和$(WindowsSDK_LibraryPath_x64)。
在分析了这一点后,我的第一个想法是,使用WINAPI类和结构的所有方法或函数都没有链接到导入库“ShirabePlatformFeatureLayer.lib”。将上面的3个libs注册为具有相同库路径的附加依赖项,并且/ VERBOSE:LIB向我显示库已附加但不是“x64 \ gdi32.lib”作为消息而是“GDI32.DLL”。同样对于其他两个。
执行/ VERBOSE:应用程序项目中的LIB显示“〜.lib”的实际相对路径,而不是“〜.DLL”。
使用WINAPI功能时,哪些方法可能导致链接/包含/重要? 具有如此多.libs的常规构建设计是否存在问题? 还有其他人有想法吗?
这里是整个受影响的代码(imho):http://pastebin.com/f7MaBBwM
如果需要进一步的信息,请告诉我。
编辑:我继续搜索并在新的MSBuild系统中提出了“项目投影”依赖项。虽然这似乎是同样的问题,但是很明显,当使用ShirabePlatformFeatureLayer.lib代码有效地被Win32TestProject使用时,“ShirabePlatformFeatureLayer.lib”依赖于导入库kernel32,gdi32和user32会导致问题。 / p>
不幸的是,由于有关该主题的10篇不同文章,我无法解决问题。 :/
编辑:咨询Rodrigo的评论我能够摆脱handle()未解决的符号。然而,gDefaultWndProcFwd的第二个似乎是逻辑/设计错误。
一旦我设法获得10点声望,我将附上WindowManager,WINAPIWindow和gDefaultWndProcFwd之间关系的图像! 这里说的是文字描述:
1)创建窗口意味着使用Window.h中的前向声明创建引用gDefaultWndProcFwd的WindowClassEx结构。
2)当窗口创建并显示时,应调用该方法,该方法参考WIndowManager :: get(key:HWND):WindowBase *;
3)如果找到,该函数在窗口指针上调用wndProc并将处理留给wndproc的指定实现。
在WindowManager.h / .cpp中声明和定义gDefaultWndProcFwd。
当我在考虑解决方案时,设计缺陷变得越来越明显! 请参阅pastebin链接以获取实际代码!
非常感谢您的帮助。
此致,Marc
答案 0 :(得分:1)
您有2个未解析的外部符号:
HWND ShirabePlatformFeatureLayer::WINAPIWindow::handle(void) const
LRESULT ShirabePlatformFeatureLayer::gDefaultWndProcFwd(HWND,UINT,WPARAM,LPARAM)
第一个可能是因为handle()
是内联的。您可能在CPP文件中定义了它(或者您忘了它?),但由于它是内联的,因此不会导出定义。相反,预计每个需要它的编译单元都可以使用它。换句话说,内联函数应该在与声明相同的头文件中定义。
第二个是没有看到你所有的代码更棘手。但我敢打赌你只是忘了写gDefaultWndProcFwd()
的定义。或者您可能在不同的命名空间或不同的参数中编写它。
请注意,静态库未链接,因此在构建库时,永远不会发生未解决的符号错误,即使缺陷位于库本身中也是如此。链接最终可执行文件时,链接器错误总是会发生。
更新:好的,我说这很棘手......重新阅读你的代码我注意到违规函数被声明了两次,并定义了一次。这本身不是问题,但请一起看两个声明:
LRESULT CALLBACK gDefaultWndProcFwd(HWND hWnd, UINT msg, LPARAM lParam, WPARAM wParam);
LRESULT CALLBACK gDefaultWndProcFwd(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
定义是:
LRESULT CALLBACK gDefaultWndProcFwd(HWND hWnd, UINT msg, LPARAM lParam, WPARAM wParam)
你看到了区别吗? WPARAM
和LPARAM
已交换!!!