Windows 64位和32位之间的共享内存接口

时间:2011-12-16 01:23:16

标签: c++ pointers 32bit-64bit

我需要在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程序正在其下运行,但我不知道如何利用它。有什么想法吗?

1 个答案:

答案 0 :(得分:5)

__based指针是另一个指针的数字偏移量。它实际上是在运行时解释的虚拟指针。

指针是64位的8字节,因此为了与32位程序兼容,您必须在64位代码中声明SharedBlock类型的指针成员,以使用4位整数而不是指针,例如:

struct sSharedBlock
{
    int32_t m_pData[...];
};
pData上的__basedgpSharedBlock,因此pData的值是gpSharedBlock的相对偏移量。使用该事实来确定数据块相对于gpSharedBlock内存块的实际字节偏移量,然后将该偏移值作为整数存储到m_pData[]中。这就是SMI内存块实际上期待的 - 偏移量,而不是真正的指针。 __based关键字只是一种使用指针处理偏移的奇特方式,而无需在代码中手动执行偏移计算。

原始代码实际上与以下内容相同,不需要__based关键字:

gpSharedBlock->m_pData[uiDataPointer] = (int32_t) ( ((char*)pData) - ((char*)gpSharedBlock) );