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

发布于 2024-12-21 06:41:12 字数 582 浏览 0 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

椵侞 2024-12-28 06:41:12

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

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

struct sSharedBlock
{
    int32_t m_pData[...];
};

pDatagpSharedBlock 上的 __based,因此 pData 的值是相对于gpSharedBlock。使用该事实来确定数据块相对于 gpSharedBlock 内存块的实际字节偏移量,然后将该偏移值作为整数存储到 m_pData[] 中。这就是 SMI 内存块实际上所期望的——一个偏移量,而不是一个真正的指针。 __based 关键字只是一种使用指针处理偏移量的奇特方法,无需在代码中手动进行偏移量计算。

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

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

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) );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文