views:

97

answers:

2

I'm learning about Thread Local Storage... (TLS) Here is my TLS Alloc code:

//global variable
DWORD g_dwTlsIndex;

//inside DLLMain:
int val= 5;
 switch (ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH:
  g_dwTlsIndex = TlsAlloc();

  if ((g_dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
  {
   printf("No more indexes available");
  }

  void *pint;
  memcpy(&pint, &val, sizeof val);

  TlsSetValue(g_dwTlsIndex, pint);
  break;

Now I try to get the value from the TLS: (in another CPP file)

// declare index value...
extern DWORD g_dwTlsIndex;

   int  data;
 LPVOID d;
 d = TlsGetValue(g_dwTlsIndex);
 memcpy(&data, &d, sizeof d);

 printf("Data: %d", data);

But data contains 0, where I put 5 in it.... What have I done wrong?

+1  A: 

A few notes:

Your error checking statement should read:

if (g_dwTLSIndex == TLS_OUT_OF_INDEXES).

As it stands, you're assigning g_dwTlsIndex twice (and thus losing the reference with the first assignment.)

Do some basic debugging:

  1. Call TlsGetValue in the line immiediately after TlsSetValue. Does that work at least?
  2. Check the return codes. TlsGetValue and TlsSetValue both return a function telling you whether the assignment was successful. Was it?
  3. Keep track of your index. You're using a global variable to store g_dwTlsIndex, so it could easily be getting altered. What is the value after alloc (use a printf to see). What is the value when you make the Get call? Do these values match?

These steps should help you find the problem.

Curmudgeonlybumbly
A: 

I assume that val is local to DllMain?

What version of Windows are you running? 64-bit Windows has 64-bit pointers and 32-bit int, so all the memcpy calls will be incorrect. Rather than using memcpy, just cast the values directly:

TlsSetValue(g_dwTLSIndex,(LPVOID)5);
int data=(int)TlsGetValue(g_dwTLSIndex);
Anthony Williams