Интерфейс разделяемой памяти между 64-битной и 32-битной Windows - PullRequest
2 голосов
/ 16 декабря 2011

Мне нужно написать код в Windows 7 (64 бита), который выполняет 32-битную программу с интерфейсом общей памяти (SMI). Точнее, программа, которую я кодирую, записывает в 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 Ответ

5 голосов
/ 16 декабря 2011

A __based указатель представляет собой числовое смещение от другого указателя.По сути, это виртуальный указатель, интерпретируемый во время выполнения.

Указатель составляет 8 байт в 64-разрядной версии, поэтому для совместимости с 32-разрядной программой необходимо объявить члены-указатели типа SharedBlock вваш 64-битный код для использования 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) );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...