Простой переход с 32 на 64 бита? - PullRequest
4 голосов
/ 30 июня 2011

Есть ли простой способ компилировать 32-битный код C в 64-битное приложение с минимальными изменениями? Код не был настроен на использование фиксированных размеров шрифта.

Меня не интересует использование 64-битной адресации памяти. Мне просто нужно скомпилировать в 64-битный двоичный файл при сохранении длинных 4-х байтов и указателей.

Что-то вроде:

#define long int32_t

Но, конечно, это нарушает ряд длительных сценариев использования и не касается указателей. Я подумал, что здесь может быть какая-то стандартная процедура.

Ответы [ 3 ]

3 голосов
/ 30 июня 2011

Кажется, что существует два ортогональных понятия "переносимости":

  1. Мой код компилируется везде из коробки.Его общее поведение одинаково на всех платформах, но детали доступных функций различаются в зависимости от характеристик платформы.

  2. Мой код содержит папку для вещей, зависящих от архитектуры.Я гарантирую, что MYINT32 всегда 32-битный, несмотря ни на что.Я успешно перенес понятие 32 бита на девятипалые пушистые светлячки Марса.

При первом подходе мы пишем unsigned int n; и printf("%u", n), и мы знаем, что кодвсегда работает, но детали, такие как числовой диапазон unsigned int, зависят от платформы и не имеют значения.( Wchar_t также входит сюда.) Это то, что я бы назвал действительно переносимым стилем.

Во втором подходе мы печатаем все определения и используем такие типы, как uint32_t.Форматированный вывод с printf вызывает тонны предупреждений, и мы должны прибегнуть к таким монстрам, как PRI32.При таком подходе мы получаем странное чувство силы и контроля, зная, что наше целое число всегда имеет ширину 32 бита, но я не решаюсь назвать это «переносимым» - оно просто упрямое.

Фундаментальная концепция, которая требуетконкретное представление - сериализация : документ, который вы пишете на одной платформе, должен быть доступен для чтения на всех других платформах.Сериализация, естественно, когда мы отказываемся от системы типов, должны беспокоиться о порядке байтов и должны принимать решение о фиксированном представлении (включая такие вещи, как кодирование текста).

Результат таков:

  • Напишите ядро ​​своей основной программы в переносимом стиле, используя стандартные языковые примитивы.
  • Пишите четко определенные, чистые интерфейсы ввода / вывода для сериализации.

Если вы будете придерживаться этого, вам никогда не следуетдаже нужно подумать о том, является ли ваша платформа 32- или 64-разрядной, с прямым или прямым порядком байтов, Mac или ПК, Windows или Linux.Придерживайтесь стандарта, и стандарт будет придерживаться вас.

2 голосов
/ 30 июня 2011

Нет, это, как правило, невозможно.Рассмотрим, например, malloc().Что должно произойти, когда он возвращает значение указателя, которое не может быть представлено в 32 битах?Как это значение указателя может быть передано в ваш код как 32-битное значение, которое будет отлично работать при разыменовании?

Это только один пример - есть множество других подобных.

Нунаписанный C-код по сути не является «32-битным» или «64-битным» в любом случае - он должен прекрасно работать при перекомпиляции в 64-битный двоичный файл без каких-либо изменений.


Ваша настоящая проблема заключается вжелая загрузить 32-битную библиотеку в 64-битное приложение.Один из способов сделать это - написать 32-битное вспомогательное приложение, которое загружает вашу 32-битную библиотеку, и 64-битную библиотеку shim, которая загружается в 64-битное приложение.Ваша 64-битная библиотека shim взаимодействует с 32-битным помощником, используя какой-то механизм IPC, запрашивая приложение-помощник для выполнения операций от его имени и возвращая результаты.

Конкретный случай - файл Matlab MEX - может бытьнемного сложнее (вам понадобится двусторонний вызов функции, чтобы 64-битная библиотека shim могла выполнять вызовы типа mexGetVariable() от имени 32-битного помощника), но это все равно должно быть выполнимо.

0 голосов
/ 30 июня 2011

Одна область, которая, вероятно, вас укусит, это если ваши 32-битные целые числа обрабатываются побитно.Если вы предполагаете, что некоторые флаги состояния хранятся в 32-битном регистре (например), или если вы делаете сдвиг битов, то вам нужно сосредоточиться на них.

Еще одно место, где можно посмотретьлюбой сетевой код, который принимает размер (и порядковый номер) целых чисел, передаваемых по каналу.После того, как они переведены в 64-битные числа, вам нужно убедиться, что вы не потеряете знаковые биты или точность.

Структуры, содержащие целые числа, больше не будут иметь одинаковый размер.Любые предположения о размере и выравнивании должны быть удалены.

...