Я пытаюсь закодировать блок растрового изображения и сохранить его в памяти (внутри вектора). Все работает нормально, пока я не попробую сделать это в многопоточном режиме. Я продолжаю получать следующие ошибки:
Ошибка C2672 'std :: invoke': не найдено совпадающей перегруженной функции
Ошибка C2893 Не удалось специализировать шаблон функции ' unknown-type std :: invoke (_Callable &&, _ Types && ...) noexcept () '
Мой код - это простой класс для съемки экрана, вызываемый внутри main (), здесь я пробую для многопоточности:
bool Screenshot::threadfunc(Gdiplus::Bitmap* bmp, int i, int j, int x, int y, int bw, int bh, std::vector<std::vector< std::vector<BYTE> >> blocksBmpBytesMatrix, std::string dataFormat)
{
Gdiplus::Bitmap* tile = bmp->Clone(x, y, bw, bh, PixelFormat24bppRGB);
// write to IStream
IStream* istream = nullptr;
CreateStreamOnHGlobal(NULL, TRUE, &istream);
// define encoding
CLSID clsid;
CLSIDFromString(L"{557cf400-1a04-11d3-9a73-0000f81ef32e}", &clsid);
Gdiplus::Status status = tile->Save(istream, &clsid, NULL);
if (status != Gdiplus::Status::Ok)
std::wcout << "ERROR" << std::endl;
return false;
// get memory handle associated with istream
HGLOBAL hg = NULL;
GetHGlobalFromStream(istream, &hg);
// copy IStream to buffer
int bufsize = GlobalSize(hg);
blocksBmpBytesMatrix[i][j].resize(bufsize);
// lock & unlock memory
LPVOID pimage = GlobalLock(hg);
memcpy(&blocksBmpBytesMatrix[i][j][0], pimage, bufsize);
GlobalUnlock(hg);
istream->Release();
return true;
};
bool Screenshot::divideIntoBlocks(HWND chwnd, int screenshotId, RECT rcMonitors, int blockHeight, int blockWidth)
{
Gdiplus::Bitmap bmp(hbwindow, nullptr);
int nrows = height / blockHeight + 1 * int((height % blockHeight) != 0);
int ncols = width / blockWidth + 1 * int((width % blockWidth) != 0);
for (int i = 0; i < nrows; i++)
{
for (int j = 0; j < ncols; j++)
{
// compute block coordinates and dimensions
int x = j * blockWidth;
int y = i * blockHeight;
int bw = ((x + blockWidth) > width) * (width % blockWidth) + ((x + blockWidth) <= width) * blockWidth;
int bh = ((y + blockHeight) > height) * (height % blockHeight) + ((y + blockHeight) <= height) * blockHeight;
// append to vecs
blocksInfo.push_back({ i, j, x, y, bw, bh });
}
}
std::vector<std::thread*> pool(nrows * ncols);
for (auto& ij : blocksInfo)
{
std::cout << ij.size() << " : " << ij[0] << "," << ij[1] << "," << ij[2] << "," << ij[3] << "," << ij[4] << "," << ij[5] << std::endl;
std::thread t(&Screenshot::threadfunc, &bmp, ij[0], ij[1], ij[2], ij[3], ij[4], ij[5], this->blockPngBytesMatrix, "png");
pool.push_back(&t);
}
for (auto& t : pool) { t->join(); }
return true;
}
любая идея, что я здесь делаю не так? или если я могу (как я могу) сделать это многопоточное кодирование?
Изменить: это Screenshot.h
class Screenshot
{
public:
// screenshot dimensions and coordinates
int width, height;
int screenx, screeny;
// inti coordinates and dimensions vectors
std::vector< std::vector<int>> blocksInfo;
// init data matrices
std::vector<std::vector< std::vector<BYTE> >> blocksPngBytesMatrix;
// init screenshot bmp and hbmp
HBITMAP hbwindow;
BITMAPINFOHEADER bi;
// init handle for display contexts
HDC hwindowDC;
HDC hwindowCompatibleDC;
// constructor
Screenshot(RECT, int, int);
// funcs
BITMAPINFOHEADER createBitmapHeader(int, int);
bool capture();
bool divideIntoBlocks(HWND, int, RECT, int, int);
bool saveToMemory(Gdiplus::Bitmap*, std::vector<BYTE>&, std::string);
bool threadfunc(Gdiplus::Bitmap*, int, int, int, int, int, int, std::vector<std::vector< std::vector<BYTE> >>, std::string);
// deconstructor
~Screenshot();
};