【问题标题】:LNK2019 DirectX unresolved external symbol; file dxerr.libLNK2019 DirectX 无法解析的外部符号;文件 dxerr.lib
【发布时间】:2018-07-05 01:17:00
【问题描述】:

出现我无法弄清楚的 LINK2019 错误。错误代码:严重性代码描述项目文件行抑制状态 错误 LNK2019 未解析的外部符号 __vsnprintf 在函数“long __stdcall StringVPrintfWorkerA(char *,unsigned int,unsigned int *,char const *,char *)”(?StringVPrintfWorkerA@@YGJPADIPAIPBD0@Z) Direct XC:\Visual Studio Programs\Direct X\Direct X\dxerr.lib(dxerra.obj) 1

main.cpp:

#include <Windows.h>
#include <memory>
#include "BlankDemo.h"


LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
    WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
    LPWSTR cmdLine, int cmdShow)
{
    UNREFERENCED_PARAMETER(prevInstance);
    UNREFERENCED_PARAMETER(cmdLine);

    WNDCLASSEX wndClass = { 0 };
    wndClass.cbSize = sizeof(WNDCLASS);
    wndClass.style = CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc = WndProc;
    wndClass.hInstance = hInstance;
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndClass.lpszMenuName = NULL;
    wndClass.lpszClassName = "DX11BookWindowClass";

    if (!RegisterClassEx(&wndClass))
        return -1;

    RECT rc = { 0, 0, 640, 480 };
    AdjustWindowRect(&rc, WS_EX_OVERLAPPEDWINDOW, FALSE);

    HWND hwnd = CreateWindowA("DX11BookWindowClass", "BlankWin32Window",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left,
        rc.bottom - rc.top, NULL, NULL, hInstance, NULL);

    if (!hwnd)
        return -1;

    ShowWindow(hwnd, cmdShow);

    std::auto_ptr<Dx11DemoBase> demo(new BlankDemo());

    // Demo Initialize
    bool result = demo->Initialize(hInstance, hwnd);

    // Error reporting if there is an issue
    if (result == false)
        return -1;

    MSG msg = { 0 };

    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        else
        {
            // Update and Draw
            demo->Update(0.0f);
            demo->Render();
        }
    }
    // Demo Shutdown
    demo->Shutdown();

    return static_cast<int>(msg.wParam);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT paintStruct;
    HDC hDC;

    switch (message)
    {
    case WM_PAINT:
        hDC = BeginPaint(hwnd, &paintStruct);
        EndPaint(hwnd, &paintStruct);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    defualt:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

// implementation of the BlankDemo class
BlankDemo::BlankDemo()
{

}

BlankDemo::~BlankDemo()
{

}

bool BlankDemo::LoadContent()
{
    return true;
}

void BlankDemo::UnloadContent()
{

}

void BlankDemo::Update(float dt)
{

}

void BlankDemo::Render()
{
    if (d3dContext_ == 0)
        return;

    float clearColor[4] = { 0.0f, 0.0f, 0.25f, 1.0f };
    d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor);

    swapChain_->Present(0, 0);
}

BlankDemo.h 文件:

#pragma once
#ifndef _BLANK_DEMO_H_
#define _BLANK_DEMO_H_
#include "Dx11DemoBase.h"

class BlankDemo : public Dx11DemoBase
{
public:
    BlankDemo();
    virtual ~BlankDemo();

    bool LoadContent();
    void UnloadContent();

    void Update(float dt);
    void Render();
};

#endif // !_BLANK_DEMO_H_

   Dx11DemoBase::Dx11DemoBase() : driverType_(D3D_DRIVER_TYPE_NULL),
featureLevel_(D3D_FEATURE_LEVEL_11_0), d3dDevice_(0), d3dContext_(0),
swapChain_(0), backBufferTarget_(0)
{

}

Dx11DemoBase::~Dx11DemoBase()
{
    Shutdown();
}

bool Dx11DemoBase::LoadContent()
{
    // Override with demo specifics, if any...
    return true;
}

void Dx11DemoBase::UnloadContent()
{
    // Override with demo specifics, if any...
}

void Dx11DemoBase::Shutdown()
{
    UnloadContent();

    if (backBufferTarget_) backBufferTarget_->Release();
    if (swapChain_) swapChain_->Release();
    if (d3dContext_) d3dContext_->Release();
    if (d3dDevice_) d3dDevice_->Release();
    d3dDevice_ = 0;
    d3dContext_ = 0;
    swapChain_ = 0;
    backBufferTarget_ = 0;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

bool Dx11DemoBase::Initialize(HINSTANCE hInstance, HWND hwnd)
{
    hInstance_ = hInstance;
    hwnd_ = hwnd;

    RECT dimensions;
    GetClientRect(hwnd, &dimensions);

    unsigned int width = dimensions.right - dimensions.left;
    unsigned int height = dimensions.bottom - dimensions.top;

    D3D_DRIVER_TYPE driverTypes[] =
    {
        D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_SOFTWARE
    };

    unsigned int totalDriverTypes = ARRAYSIZE(driverTypes);

    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
    };

    unsigned int totalFeatureLevels = ARRAYSIZE(featureLevels);

    DXGI_SWAP_CHAIN_DESC swapChainDesc;
    ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
    swapChainDesc.BufferCount = 1;
    swapChainDesc.BufferDesc.Width = width;
    swapChainDesc.BufferDesc.Height = height;
    swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
    swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.OutputWindow = hwnd;
    swapChainDesc.Windowed = true;
    swapChainDesc.SampleDesc.Count = 1;
    swapChainDesc.SampleDesc.Quality = 0;

    unsigned int creationFlags = 0;

#ifdef _DEBUG
    creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    HRESULT result;
    unsigned int driver = 0;

    for (driver = 0; driver < totalDriverTypes; ++driver)
    {
        result = D3D11CreateDeviceAndSwapChain(0, driverTypes[driver], 0,
            creationFlags, featureLevels, totalFeatureLevels, D3D11_SDK_VERSION,
            &swapChainDesc, &swapChain_, &d3dDevice_, &featureLevel_, &d3dContext_);

        if (SUCCEEDED(result))
        {
            driverType_ = driverTypes[driver];
            break;
        }
    }
    if (FAILED(result))
    {
    DXTRACE_MSG("Failed to create the Direct3d device!");
        return false;
    }

    ID3D11Texture2D* backBufferTexture;

    result = swapChain_->GetBuffer(0, _uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture);

    if (FAILED(result))
    {
        DXTRACE_MSG("Failed to get the swap chain back buffer!");
        return false;
    }
    result = d3dDevice_->CreateRenderTargetView(backBufferTexture, 0, &backBufferTarget_);

    if (backBufferTexture)
        backBufferTexture->Release();
    if (FAILED(result))
    {
        DXTRACE_MSG("Failed to create the render target view!");
        return false;
    }

    d3dContext_->OMSetRenderTargets(1, &backBufferTarget_, 0);

    D3D11_VIEWPORT viewport;
    viewport.Width = static_cast<float>(width);
    viewport.Height = static_cast<float>(height);
    viewport.MinDepth = 0.0f;
    viewport.MaxDepth = 1.0f;
    viewport.TopLeftX = 0.0f;
    viewport.TopLeftY = 0.0f;

    d3dContext_->RSSetViewports(1, &viewport);

    return LoadContent();
}

最后是 Dx11DemoBase.h 标头:

#pragma once

#ifndef _DEMO_BASE_H_
#define _DEMO_BASE_H_

#include <d3d11.h>
#include <D3DX11.h>
#include <dxerr.h>

class Dx11DemoBase
{
public:
    Dx11DemoBase();
    virtual ~Dx11DemoBase();

    bool Initialize(HINSTANCE hInstance, HWND hwnd);
    void Shutdown();

    virtual bool LoadContent();
    virtual void UnloadContent();

    virtual void Update(float dt) = 0;
    virtual void Render() = 0;

protected:

    HINSTANCE hInstance_;

    HWND hwnd_;

    D3D_DRIVER_TYPE driverType_;
    D3D_FEATURE_LEVEL featureLevel_;

    ID3D11Device* d3dDevice_;
    ID3D11DeviceContext* d3dContext_;
    IDXGISwapChain* swapChain_;
    ID3D11RenderTargetView* backBufferTarget_;
};

#endif // !_DEMO_BASE_H_

【问题讨论】:

标签: c++ visual-studio-2017 directx lnk2019


【解决方案1】:

旧版 DirectX SDK 已被弃用,因此自 Visual Studio 2010 RTM(2010 年 6 月)发布以来尚未正式更新。见Microsoft Docs

这有一些具体的含义:

  • Windows 8.0 SDK、Windows 8.1 SDK 和 Windows 10 SDK 的标头都比它们重叠的旧版 DirectX SDK 具有更新头。您仍然可以在 VS 2012、2013、2015 或 2017 中使用它,但您需要在 VC++ 目录设置中反转传统的 include/lib 路径顺序。这个Microsoft Docs 主题页面的底部还有一些其他的怪癖。另见The Zombie DirectX SDK

  • 旧版 DirectX SDK 中的 DLL 导入库缺少 Windows 8.x 或 Windows 10 SDK 中存在的一些导入。它们通常适用于所有 C/C++ 编译器,因为它们是相当标准的 Win32,没有任何特定于版本的 CRT 引用。

  • 但是,不能保证静态库在不同版本的 C/C++ 编译器之间是二进制兼容的。 dxguid.lib 里面只有一些数据,所以它通常可以工作,但dxerr.lib 有实际代码。因此,随着 VS 2015 中 C/C++ 运行时的重大变化,它不再在没有链接错误的情况下工作。

dxerr.lib问题有两种基本解决方案:

  1. 构建您自己的代码副本。它可用here。这是最强大的,因为它始终与您的编译器工具集匹配。

  2. 您可以添加legacy_stdio_definitions.lib,但请记住,您已经依赖于非常过时的文件,因此您应该努力删除/尽量减少对旧版 DirectX SDK 的使用。

许多 DirectX 11 的在线教程和书籍已经过时了。到 DirectX SDK 并仍然使用d3dx11,这也已被弃用。有许多可用于此功能的开源替代品。见Living without D3DX

话虽如此,这个问题已经在 StackOverflow 上得到了回答,如果你刚刚搜索过 dxerr 就会出现。

【讨论】:

  • 第一个解决方案中的此处链接重定向到一些随机博客:walbourn.github.io,其中包含许多与问题文章无关的不同内容。
  • 没有 D3DX 的生活链接也指向同一个博客,并且没有提供与问题中的问题相关的任何信息。
  • 不推荐使用 Blogs@MSDN,因此我的博客内容已迁移到 walbourn.github.io。唉,重定向不起作用页面到页面,这就是你最终出现在主页上的原因。更新了链接。
【解决方案2】:

按照此答案的建议,将legacy_stdio_definitions.lib 添加到Project properties &gt; Configuration Properties &gt; Linker &gt; Input 中的Additional dependencies 列表:https://stackoverflow.com/a/34230122/6693304

【讨论】:

    猜你喜欢
    • 2020-07-09
    • 2012-07-10
    • 2019-03-05
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    相关资源
    最近更新 更多