Data with thread storage duration may not have dll interface c++

125 views Asked by At

I am using ThreadPool (see header and source) (based on ConcurrentQueue) from Antoine Savine's repo inside a Windows DLL (in the repo he uses it in an XLL) code as follows :

BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpvReserved)  // reserved
{
    // Perform actions based on the reason for calling.
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        // Initialize once for each new process.
        // Return FALSE to fail DLL load.
        ThreadPool::getInstance()->start(std::thread::hardware_concurrency() - 1);
        break;

    case DLL_THREAD_ATTACH:
        // Do thread-specific initialization.
        break;

    case DLL_THREAD_DETACH:
        // Do thread-specific cleanup.
        break;

    case DLL_PROCESS_DETACH:

        if (lpvReserved != nullptr)
        {
            break; // do not do cleanup if process termination scenario
        }
        // Perform any necessary cleanup.
        ThreadPool::getInstance()->stop();
        break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

in the dllmain.cpp that I added especially because of wanting to use ThreadPool. (In the XLL code in his repo Savine uses ThreadPool::getInstance()->start in the xllopen method and ThreadPool::getInstance()->stop() in the xllclose method - so I mimicked that in the dllmain.cpp setup - and used ThreadPool freely after without any problem.)

Using ThreadPool after in my DLL code :

ThreadPool* pool = ThreadPool::getInstance();
const size_t nThread = pool->numThreads();
// I declare objects per threads etc ... and then ...
// I Reserve memory for futures
std::vector<TaskHandle> futures;
futures.reserve(somesizet);
futures.push_back(pool->spawnTask([&, firstPath, pathsInTask]()
{
    //stuff
}));

This code is correct functionally. (Meaning : when I am using it in an .EXE, it compiles and works as intended.) The problem is that if I compile without exporting anything ThreadPool related, I have errors :

unresolved external symbol "private: static class ThreadPool ThreadPool::myInstance" (?myInstance@ThreadPool@@0V1@A)
unresolved external symbol "private: static unsigned __int64 ThreadPool::myTLSNum" (?myTLSNum@ThreadPool@@0_KA)

and if I export these (static) member and method (or the ThreadPool class), at compilation I have the following error :

'private: static unsigned __int64 ThreadPool::myTLSNum': data with thread storage duration may not have dll interface

I looked for the latter error and came accross thread_local C++11, Error C2492 in VS2015 which frightens me a lot as it implies that I cannot use ThreadPool as it is implemented in my DLL context. (Which by the way clashes in my mind with the fact that it is perfectly useable in the XLL context in Savine's repo, while an XLL is just ... a C++ DLL using Excel C Api...)

I there a way to make it work ?

(I use Microsoft Visual Studio Professional 2022 Version 17.7.5 last update and compile C++ with /std:c++-latest/)

0

There are 0 answers