我正在尝试在控制台应用程序中使用“多线程”,在该应用程序中我正在使用SetPixel()在缓冲区中呈现图像,而最近我无法再编译我的应用程序,

Boot.cpp:

#include <stdio.h>
#include <thread>

#include "Tes32/GraphicsDevice/GraphicsController.h"
#include "Tes32/AudioDevice/AudioController.h"

void ShowConsoleCursor(bool showFlag)
{
    HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);

    CONSOLE_CURSOR_INFO     cursorInfo;

    GetConsoleCursorInfo(out, &cursorInfo);
    cursorInfo.bVisible = showFlag; // set the cursor visibility
    SetConsoleCursorInfo(out, &cursorInfo);
}

int main(int argc, char** argv) {


    printf("\n\nInitializing AudioDevice...");
    Tes32::AudioDevice::AudioController a_ctx;



    printf("Initializing GraphicsDevice...");
    Tes32::GraphicsDevice::GraphicsController g_ctx();

    printf("\n\tCreating Thread %%gctx.RenderLoop");

    system("sleep 1");
    system("clear");
    ShowConsoleCursor(false);


    std::thread g_ctx_renderloop(&Tes32::GraphicsDevice::GraphicsController::RenderThread, g_ctx);




    g_ctx_renderloop.join();
}

GraphicsController.cpp:

#include "GraphicsController.h"


Tes32::GraphicsDevice::GraphicsController::GraphicsController()
{

    this->display_ctx = GetConsoleWindow();
    this->render_ctx = GetDC(display_ctx);
    this->display_handle = GetStdHandle(STD_OUTPUT_HANDLE);

    std::vector<std::string> driversettings;

    int width, height;
    Tes32::GraphicsDevice::InternalTypes::ColorPixel fillclr;

    std::ifstream file(std::experimental::filesystem::current_path().string() + "\\Debug\\HDD\\System\\Drivers\\tesvga.inf");
    if (file.is_open()) {
        printf("LOADED!");
        std::string line;
        while (getline(file, line)) {
            driversettings.push_back(line);
        }
        file.close();
    }

    for (std::string s : driversettings) {
        std::vector<std::string> Split = this->split(s, "=");

        if (Split[0] == "GraphicsMode") {
            if (Split[1] == "640x480") {
                this->graphicsmode = 0;
                width = 640;
                height = 480;
                Tes32::GraphicsDevice::OutputWindow::SetOutputWindowSize(this->display_handle, { 0,0 }, { 64, 64 });
            }
        }
        else if (Split[0] == "FillColor") {
            std::vector<std::string> color = this->split(Split[1], ",");

            int r, g, b;
            r = atoi(color[0].c_str());
            g = atoi(color[1].c_str());
            b = atoi(color[2].c_str());

            r--; g--; b--;

            this->fillcolor = { (char)r, (char)g, (char)b };
            fillclr = { (char)r, (char)g, (char)b };

        }
        else if (Split[0] == "ColorAdjust_R") { this->clr_adjust_r = atoi(Split[1].c_str()); }
        else if (Split[0] == "ColorAdjust_G") { this->clr_adjust_g = atoi(Split[1].c_str()); }
        else if (Split[0] == "ColorAdjust_B") { this->clr_adjust_b = atoi(Split[1].c_str()); }


    }

    this->display_buffer = new Tes32::GraphicsDevice::InternalTypes::ColorPixel[width * height];

    for (int y = 0; y != height; y++) {
        for (int x = 0; x != width; x++) {
            this->display_buffer[x + width * y] = fillclr;
        }
    }

    this->ctx_size = { width, height };


}



bool Tes32::GraphicsDevice::GraphicsController::Destroy()
{
    try {
        this->KeepRendering = false;
        delete this->display_buffer;
        ReleaseDC(this->display_ctx, this->render_ctx);
    }
    catch (std::exception& e){
        printf("!!!KERNEL PANIC!!! g_ctx:: Failed to Destroy GraphicsController // Details: %s\n", e.what());
        return false;
    }

    return true;
}

void Tes32::GraphicsDevice::GraphicsController::ModifySyncRegisters(bool sRender, bool sStayWhileNotRendering)
{
    this->KeepRendering = sRender;
    this->Hold = sStayWhileNotRendering;
}

std::vector<std::string> Tes32::GraphicsDevice::GraphicsController::split(const std::string& str, const std::string& delim)
{
    std::vector<std::string> tokens;
    size_t prev = 0, pos = 0;
    do
    {
        pos = str.find(delim, prev);
        if (pos == std::string::npos) pos = str.length();
        std::string token = str.substr(prev, pos - prev);
        if (!token.empty()) tokens.push_back(token);
        prev = pos + delim.length();
    } while (pos < str.length() && prev < str.length());
    return tokens;
}

void Tes32::GraphicsDevice::GraphicsController::RenderThread()
{
    int start, movement, end;


    start = 0;
    movement = 1;
    end = 480;



    while (this->Hold) {
        if (this->KeepRendering) {
            for (int y = start; y != end; y++) {
                for (int x = 0; x != this->ctx_size.x; x++) {


                    SetPixel(
                        render_ctx,
                        x, y,
                        RGB(
                            display_buffer[x + this->ctx_size.x * y].r,
                            display_buffer[x + this->ctx_size.x * y].g,
                            display_buffer[x + this->ctx_size.x * y].b
                        )
                    );

                }
            }
        }
    }
}


我遇到的2个错误是:

C2893:
Severity    Code    Description Project File    Line    Suppression State
Error   C2893   Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept(<expr>)'   WolfOS_2_HDD    V:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\include\thread  35


C2672:
Severity    Code    Description Project File    Line    Suppression State
Error   C2672   'std::invoke': no matching overloaded function found    WolfOS_2_HDD    V:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\include\thread  39


编译日志:
1>------ Build started: Project: WolfOS_2_HDD, Configuration: Debug Win32 ------
1>Boot.cpp
1>V:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\include\thread(39): error C2672: 'std::invoke': no matching overloaded function found
1>V:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\include\thread(46): note: see reference to function template instantiation 'unsigned int std::thread::_Invoke<_Tuple,0,1>(void *) noexcept' being compiled
1>        with
1>        [
1>            _Tuple=_Tuple
1>        ]
1>V:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\include\thread(52): note: see reference to function template instantiation 'unsigned int (__stdcall *std::thread::_Get_invoke<_Tuple,0,1>(std::integer_sequence<unsigned int,0,1>) noexcept)(void *)' being compiled
1>G:\WolfOS_2_HDD\Boot.cpp(36): note: see reference to function template instantiation 'std::thread::thread<void(__thiscall Tes32::GraphicsDevice::GraphicsController::* )(void),Tes32::GraphicsDevice::GraphicsController(__cdecl &)(void),void>(_Fn &&,Tes32::GraphicsDevice::GraphicsController (__cdecl &)(void))' being compiled
1>        with
1>        [
1>            _Fn=void (__thiscall Tes32::GraphicsDevice::GraphicsController::* )(void)
1>        ]
1>V:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\include\chrono(595): note: see reference to class template instantiation 'std::chrono::duration<double,std::ratio<1,1>>' being compiled
1>V:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\include\chrono(172): note: see reference to class template instantiation 'std::chrono::duration<__int64,std::nano>' being compiled
1>V:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\include\chrono(574): note: see reference to class template instantiation 'std::chrono::time_point<std::chrono::steady_clock,std::chrono::steady_clock::duration>' being compiled
1>V:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\include\thread(35): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept(<expr>)'
1>V:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\include\thread(35): note: With the following template arguments:
1>V:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\include\thread(35): note: '_Callable=void (__thiscall Tes32::GraphicsDevice::GraphicsController::* )(void)'
1>V:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\include\thread(35): note: '_Types={Tes32::GraphicsDevice::GraphicsController (__cdecl *)(void)}'
1>GraphicsController.cpp
1>Generating Code...
1>Done building project "WolfOS_2_HDD.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


我正在使用Visual Studio Community2019。在此先感谢!

最佳答案

一个更简单的示例是:

#include <thread>

struct GraphicsController
{
    void RenderThread()
    {
    }
};

int main()
{
    GraphicsController g_ctx();
    std::thread g_ctx_renderloop(&GraphicsController::RenderThread, g_ctx);
}

您代码中的问题是most vexing parseGraphicsController g_ctx();声明一个返回GraphicsController而不是GraphicsController对象的函数。要修复它,只需除去括号:
int main()
{
    GraphicsController g_ctx;
    std::thread g_ctx_renderloop(&GraphicsController::RenderThread, g_ctx);
}

编译器错误输出的关键部分是最后两行:

_Callable=void (__cdecl GraphicsController::* )(void)
_Types={GraphicsController (__cdecl *)(void)}

这些告诉您正在使用的模板类型,_Callable是第一个参数,可以作为GraphicsController类中的方法指针正确使用。 _Types是函数参数的列表,它应该只是{GraphicsController*},但实际上是指向没有返回GraphicsController的参数的函数的函数指针。

关于c++ - 线程时为C2893和C2672,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60422129/

10-14 18:52