Boost logo

Boost :

Subject: Re: [boost] Fwd: [Thread] Solution to conflict with MFC?
From: Vyacheslav Lanovets (xentrax_at_[hidden])
Date: 2013-02-28 03:41:21


Hi,

In MSVC __declspec (selectany) cannot be used for functions but it's
possible to emulate using "__declspec(noinline) inline"
(http://blogs.msdn.com/b/freik/archive/2005/10/26/485276.aspx). Seems to
produce same mangled name as normal _cdecl.

The workaround from Anthony Williams works well to make MFC work with
boost::thread but it should be included only once per project.

For boost linked dynamically, the following file allows inclusion in any
number of files in the project. Actually, I included it in StdAfx.h. Did not
give it extensive testing but seems to work both on Windows CE / Windows
Mobile and Win32 builds.

Comments are welcome.
 

#ifdef _MSC_VER

#if !defined(_LIB) && (defined(_AFXEXT) || defined(_USRDLL) ||
defined(_WINDLL)) // DLLs only

#include <boost/thread/thread.hpp>
#include <boost/thread/detail/tss_hooks.hpp>

// Use custom entry point to call into boost::thread hooks
// It's safe to call hooks before global data initialization by CRTL because
boost::thread overrides RawDllMain which is also called earlier than CRTL's
DLLMain.
#pragma comment(linker, "/ENTRY:tps_entry")

extern "C" BOOL WINAPI
_DllMainCRTStartup(
                                   HANDLE hDllHandle,
                                   DWORD dwReason,
                                   LPVOID lpreserved
                                   );

// "__declspec(noinline) inline" is used to get __declspec(selectany) flag
// because __declspec(selectany) cannot be applied to functions directly
// Could use template for that but then mangled name should be designated as
entry point
extern "C" __declspec(noinline) inline BOOL WINAPI tps_entry(
        HANDLE hDllHandle,
        DWORD dwReason,
        LPVOID lpreserved
        )
{
        // here define DLL hook (and EXE hook below)
        switch (dwReason)
        {
        case DLL_PROCESS_ATTACH:
                boost::on_process_enter();
                break;
        case DLL_THREAD_ATTACH:
                boost::on_thread_exit();
                break;
        case DLL_THREAD_DETACH:
                boost::on_thread_exit();
                break;
        case DLL_PROCESS_DETACH:
                boost::on_process_exit();
                break;
        }
        return _DllMainCRTStartup(hDllHandle, dwReason, lpreserved);
}

// Special protocol to indicate to boost::thread that we did support custom
tss cleanup hooks
// Use of "__declspec(noinline) inline" allows multiple definition across
the project as results in __declspec(selectany) flag
namespace boost
{
        __declspec(noinline) inline void tss_cleanup_implemented()
        {
        }
}

// Just to force inclusion of custom entry point to obj. Template is used to
get __declspec(selectany) flag.
// Inline functions are not compiled in; even under debug.
template <typename> int tps_dummy_reserved()
{
        return &boost::tss_cleanup_implemented && &tps_entry;
}
template int tps_dummy_reserved<int>();

#endif // DLLs only

#endif

--
View this message in context: http://boost.2283326.n4.nabble.com/Fwd-Thread-Solution-to-conflict-with-MFC-tp3477977p4643587.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk