我需要在Windows 7(64位)中编写代码,执行具有共享内存接口(SMI)的32位程序。更确切地说,我编写的程序写入SMI,32位程序从该SMI读取。
我遇到的第一个问题是我无法访问32位程序的源代码,这是无法解决的问题。第二个问题是SMI存储所写信息的地址。使用以下代码将此指向存储为基指针:
gpSharedBlock->m_pData[uiDataPointer] = (char __based(gpSharedBlock)*)pData;
pData是指向我们正在编写的数据的指针,gpSharedBlock-> m_pData [i]指向存储的第i个元素。
可能从这里你已经注意到了这个问题; W32中的指针是4个字节,而W64中的指针是8个字节。然后,由于存储的值是64位指针,因此最终由32位程序读取的值不是所需的值。
我的问题是:有没有办法将64位地址转换为32位地址,以便正在运行的程序读取正确的信息?
我已经阅读过关于WOW64的内容,我认为W32程序正在其下运行,但我不知道如何利用它。有什么想法吗?
答案 0 :(得分:5)
__based
指针是另一个指针的数字偏移量。它实际上是在运行时解释的虚拟指针。
指针是64位的8字节,因此为了与32位程序兼容,您必须在64位代码中声明SharedBlock类型的指针成员,以使用4位整数而不是指针,例如:
struct sSharedBlock
{
int32_t m_pData[...];
};
pData
上的__based
为gpSharedBlock
,因此pData
的值是gpSharedBlock
的相对偏移量。使用该事实来确定数据块相对于gpSharedBlock
内存块的实际字节偏移量,然后将该偏移值作为整数存储到m_pData[]
中。这就是SMI内存块实际上期待的 - 偏移量,而不是真正的指针。 __based
关键字只是一种使用指针处理偏移的奇特方式,而无需在代码中手动执行偏移计算。
原始代码实际上与以下内容相同,不需要__based
关键字:
gpSharedBlock->m_pData[uiDataPointer] = (int32_t) ( ((char*)pData) - ((char*)gpSharedBlock) );