使用WINAPI的复杂库依赖项目中未解析的外部符号

时间:2014-06-18 22:41:00

标签: c++ c winapi dll static-libraries

现在搜索了几天我决定在这里发一个问题,并希望有人有最终的想法或建议。

我编写了一个由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

1 个答案:

答案 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)

你看到了区别吗? WPARAMLPARAM已交换!!!