Reputation: 137
I need to write code in Windows 7 (64 bits) that executes a 32-bits program that has a Shared Memory Interface (SMI). More precisely, the program I am coding writes into the SMI and the 32-bits program reads from this SMI.
The first problem that I have is that I don't have access to the source code of the 32-bit program, problem that can't be solved. The second problem is that the SMI stores the address of the information that is written. This pointed is stored as a based pointer using the following code:
gpSharedBlock->m_pData[uiDataPointer] = (char __based(gpSharedBlock)*)pData;
Were pData is a pointer to the data we are writing, and gpSharedBlock->m_pData[i] points to the i^th element stored.
Probably from here you have already noticed the problem; a pointer in W32 is 4 bytes while a pointer in W64 is 8 bytes. Then, since the value stored is a 64 bit pointer, the value finally read by the 32-bits program is not the desired one.
My question is: is there a way to do a translation of the 64-bit address to a 32-bit address such that the program that is running reads the correct information?
I have read about WOW64, and I suppose that the W32 program is running under it, but I don't know how to take advantage of that. Any ideas?
Upvotes: 2
Views: 1302
Reputation: 595412
A __based
pointer is a numeric offset from another pointer. It is effectively a virtual pointer interpretted at runtime.
A pointer is 8 bytes in 64-bit, so to be compatible with the 32-bit program, you will have to declare the pointer members of the SharedBlock type in your 64-bit code to use 4-bit integers instead of pointers, eg:
struct sSharedBlock
{
int32_t m_pData[...];
};
pData
is __based
on gpSharedBlock
, so the value of pData
is a relative offset from the value of gpSharedBlock
. Use that fact to determine the actual byte offset of your data block relative to the gpSharedBlock
memory block, and then store that offset value into m_pData[]
as an integer. That is what the SMI memory block is actually expecting anyway - an offset, not a real pointer. The __based
keyword is just a fancy way of handling offsets using pointers without doing the offset calculations manually in code.
The original code is effectively the same as the following without needing the __based
keyword:
gpSharedBlock->m_pData[uiDataPointer] = (int32_t) ( ((char*)pData) - ((char*)gpSharedBlock) );
Upvotes: 5