2

Got a LINK2019 error that I can't figure out. Error code: Severity Code Description Project File Line Suppression State Error LNK2019 unresolved external symbol __vsnprintf referenced in function "long __stdcall StringVPrintfWorkerA(char *,unsigned int,unsigned int *,char const *,char *)" (?StringVPrintfWorkerA@@YGJPADIPAIPBD0@Z) Direct X C:\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 file:

#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();
}

And lastly, the Dx11DemoBase.h header:

#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_
K.J. Shamberger
  • 69
  • 1
  • 2
  • 8
  • Somehow you have managed to not link with the Standard C Runtime library. If you look up `_vsnprintf` on MSDN you will see it is in the C Runtime library: https://msdn.microsoft.com/en-us/library/1kt27hek.aspx Check your linker options. – Richard Critten Jan 25 '18 at 17:38
  • This is probably a dumb question, but what am I looking for in my linker options, exactly? And how would I link with the Standard C Runtime library? – K.J. Shamberger Jan 25 '18 at 18:07
  • Possible duplicate of [Unresolved external symbol \_\_vsnprintf .... (in dxerr.lib)?](https://stackoverflow.com/questions/31053670/unresolved-external-symbol-vsnprintf-in-dxerr-lib) – Asesh Jan 26 '18 at 10:23

2 Answers2

2

The legacy DirectX SDK is deprecated, so it hasn't been officially updated since the release of Visual Studio 2010 RTM (June 2010). See Microsoft Docs

This has a few specific implications:

  • The Windows 8.0 SDK, Windows 8.1 SDK, and Windows 10 SDK all have newer headers than the legacy DirectX SDK where they overlap. You can still make use of it with VS 2012, 2013, 2015, or 2017 but you need to reverse the traditional include/lib path order in the VC++ Directories settings. There are a few other quirks covered at the bottom of this Microsoft Docs topic page. See also The Zombie DirectX SDK.

  • The DLL import libraries in the legacy DirectX SDK are missing some of the imports that are present in the Windows 8.x or Windows 10 SDK. They generally work fine with all C/C++ compilers because they are fairly standard Win32 without any version-specific CRT references.

  • Static libraries, however, are not guaranteed to be binary compatible from version to version of the C/C++ compiler. dxguid.lib just has some data in it, so it generally works, but dxerr.lib has actual code. Hence with the major changes in the C/C++ Runtime in VS 2015, it no longer works without link errors.

There are two basic solutions to the dxerr.lib problem:

  1. Build your own copy of the code. It's available here. This is the most robust as it will always match your compiler toolset.

  2. You can add legacy_stdio_definitions.lib, but keep in mind that you are already relying on very out-dated files so you should work to remove/minimize use of the legacy DirectX SDK over time.

Many online tutorials for DirectX 11 and books are outdated w.r.t. to the DirectX SDK and still use d3dx11 which is also deprecated. There are numerous open source replacements available for this functionality. See Living without D3DX.

All that said, this question has already been answered on StackOverflow and would have shown up if you just searched dxerr.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • The here link in the first solution redirects to some random blog: https://walbourn.github.io/ with many different unrelated to the problem in question articles in it. – KulaGGin Nov 07 '20 at 13:54
  • The Living without D3DX link also leads to the same blog and doesn't provide any information related to the problem in the question. – KulaGGin Nov 07 '20 at 13:56
  • The Blogs@MSDN were deprecated, so my blog content was migrated to ``walbourn.github.io``. Alas the redirect doesn't work page-to-page, which is why you ended up on the home page. Updated the links. – Chuck Walbourn Nov 08 '20 at 06:24
1

Add legacy_stdio_definitions.lib to Additional dependencies list in the Project properties > Configuration Properties > Linker > Input as recommended in this answer: https://stackoverflow.com/a/34230122/6693304

KulaGGin
  • 943
  • 2
  • 12
  • 27