As explained in the answers you referenced, the [ThreadStatic]
functionality is implemented by the .NET runtime, not by the C# compiler.
That means, you'd need to reverse-engineer the runtime's data structures to get access to the data you want.
Alternatively, you can use the ICorProfilerInfo
interface. This is an unmanaged interface, as you require.
In particular, you'd need the ICorProfilerInfo2::GetThreadStaticAddress
method. It accepts a class ID, a field ID, and a thread ID as input arguments and provides an address of the field's value that is local to the thread with the specified ID.
If you're interested in how this works, you can check e.g. the Core CLR's implementation (search for the GetThreadStaticAddress2
method, also look threads.cpp for GetStaticFieldAddrNoCreate
). The Core CLR doesn't utilize the OS TLS; instead, it maintains its own table of so called ThreadLocalBlock
s and ThreadLocalModule
s where the data is stored.
There's also a managed Microsoft.Diagnostics.Runtime (CLR MD) implementation. It should also provide an access to the thread-local values. However, it seems to be broken now, as a comment says:
// TODO: Renable when thread statics are fixed.