views:

139

answers:

4

I'm converting a C++ application in C# and managing to work my way through most of it. However I'm stuck with the following statement:

#define GET_SHCALL_ID(L)                           (((L) >> 24) & 0x000000FF)

It's called by another part of the application that receives a Window Message and is passing in the lParam to this call, as shown below:

// We perform and event handling to display state as required here..
LRESULT CShockSampleDlg::OnShockCallEvent(WPARAM wParam, LPARAM lParam)
{
  // Pass events here so that they will be displayed int the m_LogMessages window.
  OnDebugCallEvents(wParam, lParam);

  UINT callID = GET_SHCALL_ID(lParam);
  UINT chanID = GET_SHCHAN_ID(lParam);
  UINT info   = GET_SHCHAN_INFO(lParam);

So my questions are:

  • What is the macro/method doing?
  • What would be the equivalent in C#?
+5  A: 

Consider that 32-bit integer be composed of 4 octets (bytes):

  zzyyxxww
0x12345678

That operations extracts the "zz" (0x12) byte.

But that's just the implementation. The usage is clearly written in the name GET_SHCALL_ID — It gets the shock call ID from the lParam.

C# and C++ share many operators, in this case the function is just the same.

uint GET_SHCALL_ID(uint lParam) { return (lParam >> 24) & 0xFF; }
KennyTM
big-z
+1 for explaining and giving code snippet..
Favonius
@zilgo: (1) It is possible `LPARAM` is a 64-bit integer instead of 32-bit. (2) It is possible `LPARAM` is signed instead of unsigned.
KennyTM
Antonio Perez
+1  A: 

It takes the most significant 8 bits of a 32-bit value so that 0x12345678, for example, becomes 0x12.

Typically, the lParam will carry a few bits of information and this is getting one of them. It looks like that's the shock call identifier and the other two macros will get different bits out of the lParam for other purposes (channel ID and channel information).

C# would be something like:

uint lParam = 0x12345678;            // for testing.
uint callID = (lParam >> 24) & 0xff;
uint chanID = ...;                   // These depend on where the
uint info   = ...;                   // other bits are in lParam.

Technically, the & 0xff is not needed for this case but will be if lParam happens to be a signed int (since negative numbers are sign-extended) or a value larger than 32 bits (which is unlikely).

paxdiablo
A: 

In C# this is the same, but without macro:

int result = ( n >> 24 ) & 0xFF;

Alex Farber
A: 

This is bitshifting the bit-value of L to the right by 24 bits, (I don't know what LPARAM is / how long it is so I can't tell you what's left), and then it's bit-wise ANDing the value with 0xFF, so as to only keep the remaining 8-bit values of the variable.

Gabe