Могут ли 32-битные и 64-битные работать вместе?

Может ли 64-битная библиотека работать в 32-битном приложении? Например, мой графический интерфейс приложения использует 32-битный Qt. И мое бизнес-ядро — это 64-битная библиотека. ОС является 64-битной. Могут ли они работать вместе и как? Благодарю.

16

Решение

Вкратце: вы не можете связать 32-битное приложение с 64-битной библиотекой.

Вы можете запустить 32-разрядное приложение, используя 32-разрядные разделяемые библиотеки в 64-разрядной ОС (по крайней мере, на всех популярных 32- / 64-разрядных процессорах, таких как AMD, Intel и Sparc). Но это не касается каких-либо библиотек.

Более длинный ответ: я участвовал (на окраине) в некоторых командах, которые разрабатывали 64-битное ядро ​​Linux для x86. Вкратце (по сравнению со всем проектом обсуждения продолжались довольно много часов) были некоторые дискуссии о том, как технически можно сделать эту работу. Краткое резюме этого заключается в том, что в 64-битных есть регистры, которые не доступны в 32-битных. Существует также проблема адресов памяти и дополнительных 32-битных регистров. Все это может быть решено, если сама библиотека «знает», что это 32-битная совместимая библиотека. Но тогда у нас в основном есть 64-битная библиотека, написанная как 32-битная, и мы вроде как потеряли смысл.

«Больше регистров» может не применяться к некоторым процессорам, но больший диапазон адресов / битов регистров определенно применим ко ВСЕМ 32- и 64-битным совместимым процессорам. И я не знаю ни одного процессора, который бы позволял 32-битному коду вызывать 64-битную разделяемую библиотеку или статическую библиотеку. Это просто не работает, если код специально не написан, чтобы справиться с этим, что лишает смысла иметь общую 64-битную библиотеку для поддержки 32-битных приложений.

Редактировать:

Выше обсуждается связывание одного исполняемого модуля, например, исполняемый файл, общая библиотека или статическая библиотека. Все это должно быть «одна битность», 32 или 64 — без микширования.

Когда процесс обращается к другому процессу (например, к приложению с графическим интерфейсом, которое отображает состояние процесса, отличного от графического интерфейса пользователя), пока два процесса используют один и тот же протокол [и, как правило, IPC не разрешает передачу указателей в любом случае, поэтому 32- / 64-битное преобразование не такая большая проблема], у вас может быть один 32-битный процесс, а другой 64-битный.

19

Другие решения

Да, но это большая неприятность.

Во-первых, ядро ​​отличается от библиотеки. Как правило, библиотека становится видимой в виртуальном адресном пространстве вашего процесса; он разделяет адресное пространство с вашим собственным кодом. Вызов библиотечной процедуры — это просто вызов подпрограммы.

Напротив, чтобы запросить службы у ядра, ваш процесс выполняет специальную инструкцию для генерации ловушки. Эта ловушка заставляет процессор выполнять некоторые специальные действия, в том числе сохранять регистры вашего процесса и другое состояние в памяти (или в специальных регистрах процессора, к которым у вас нет нормального доступа), изменять различные режимы в процессоре, чтобы сделать их подходящими для ядра, и изменив счетчик программы, чтобы он указывал на инструкции для ядра. Тогда ядро ​​работает. На этом этапе ядро ​​может работать в 64-битном режиме, когда ваш процесс работает в 32-битном режиме. Тем не менее, ядро ​​разработано с учетом этих различий. Когда ваше ядро ​​проверяет ваш процесс, чтобы увидеть, что вы запрашиваете, оно ищет информацию и структуры данных, зная, что ваш процесс работал в 32-битном режиме. Ядро может поддерживать как 32-битные, так и 64-битные процессы, оно просто по-разному относится к каждому типу процессов.

Конечно, это предполагает, что используемое вами 64-битное ядро ​​поддерживает 32-битные процессы.

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

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

6

Я работаю над приложением, которое делает именно это. Ядро приложения — x64 (и использует Qt), но оно должно взаимодействовать с некоторым оборудованием, для которого у меня есть только 32-битная библиотека от производителя. Я реализовал это, имея два приложения по 64 бита для ядра и графического интерфейса и 32 бита, которые управляют оборудованием и связываются с основными приложениями с помощью QSharedMemory. Оба приложения основаны на Qt (64 и 32 бита соответственно).

2

Если вы работаете в Windows, то ваше приложение, скомпилированное для 32b, может работать в хост-системе Windows 64b: взгляните на WOW64 подсистема, встроенная в 64b Windows.

Сказав это, вы можете не смешанный код, скомпилированный для 32b, с кодом, скомпилированным для 64b. То есть библиотека, созданная для 32b, не может быть связана с кодом 64b, и наоборот. (Различные соглашения о вызовах, расположение стеков, исключая перемотку, …)

1