Преобразование кода Win16 C в Win32
В общем, что нужно сделать для преобразования 16-разрядной программы Windows в Win32? Я уверен, что я не единственный человек, который наследует кодовую базу и ошеломлен, чтобы найти 16-битный код, скрывающийся в углах.
Код, о котором идет речь, - C.
Ответы
Ответ 1
- Значения
wParam
и lParam
во многих местах изменились. Я сильно поощряю вас быть параноидальным и конвертировать как можно больше, чтобы использовать сообщения для взлома. Они не избавят вас от головных болей. Если есть только один совет, который я мог бы вам дать, это было бы так.
- Пока вы используете взломщики сообщений, также включайте
STRICT
. Это поможет вам поймать базу кода Win16 с помощью int
, где он должен использовать HWND
, HANDLE
или что-то еще. Преобразование их значительно поможет С# 9 в этом списке.
-
hPrevInstance
бесполезен. Убедитесь, что он не используется.
- Убедитесь, что вы используете Unicode-дружественные вызовы. Это не означает, что вам нужно преобразовать все в
TCHAR
s, но лучше заменить OpenFile
, _lopen
и _lcreat
на CreateFile
, чтобы назвать очевидный
-
LibMain
теперь DllMain
, и весь формат библиотеки и соглашения экспорта отличаются
- У Win16 не было VMM.
GlobalAlloc
, LocalAlloc
, GlobalFree
и LocalFree
следует заменить более современными эквивалентами. По завершении очистите вызовы LocalLock
, LocalUnlock
и друзей; они теперь бесполезны. Не то, чтобы я мог представить, как ваше приложение делает это, но убедитесь, что вы не зависите от WM_COMPACTING
, пока вы там.
- У Win16 также не было защиты памяти. Убедитесь, что вы не используете
SendMessage
или PostMessage
для отправки указателей в окна без обработки. Вам нужно переключиться на более современный механизм IPC, например, на трубы или файлы с отображением памяти.
- Win16 также не имел превентивной многозадачности. Если вам нужен быстрый ответ из другого окна, было бы здорово позвонить
SendMessage
и дождаться, пока сообщение будет обработано. Это может быть плохой идеей. Подумайте, не лучший ли вариант PostMessage
.
- Изменение указателя и целого числа. Не забудьте тщательно проверять все, что вы читаете или записываете данные на диск, особенно если это структуры Win16. Вам придется вручную переделать их для обработки более коротких значений. Опять же, наименее болезненный способ справиться с этим будет заключаться в том, чтобы использовать взломщики сообщений, где это возможно. В противном случае вам нужно вручную выследить и преобразовать
int
в DWORD
и так далее, где это применимо.
- Наконец, когда вы пригвоздили очевидное, рассмотрите возможность проверки 64-разрядных компиляций. Многие проблемы, связанные с переходом от 16 до 32 бит, такие же, как и от 32 до 64, а Visual С++ на данный момент довольно умна. Вы не только поймаете некоторые затяжные проблемы; вы тоже будете готовы к последующей миграции Win64.
EDIT. Как указывает @ChrisN, официальное руководство по переносу приложений Win16 на Win32 по-прежнему доступно, и оба fleshes вне и добавляет к моим пунктам выше.
Ответ 2
Помимо правильной настройки вашей среды сборки, вот несколько особенностей, которые вам нужно будет решить:
-
structs, содержащие int, необходимо будет изменить на короткий или расширенный с 16 до 32 бит. Если вы измените размер структуры и загрузите/сохраните на диск, вам понадобится код обновления файла данных для записи.
-
Данные окна часто хранятся с помощью дескриптора окна с использованием GWL_USERDATA. Если вы расширите некоторые данные до 32 бит, ваши смещения изменятся.
-
Структуры POINT и SIZE имеют 64 бита в Win32. В Win16 они были 32 бита и могут быть возвращены как DWORD (вызывающий будет разделять возвращаемое значение на два 16-битных значения). Это больше не работает в Win32 (то есть Win32 не возвращает результаты 64 бит), и функции были изменены, чтобы принять указатели для хранения возвращаемых значений. Вам нужно будет отредактировать все это. Это влияет на API, такие как GetTextExtent. Эта же проблема также относится к некоторым сообщениям Windows.
-
Использование INI файлов не рекомендуется в Win32 в пользу реестра. Пока функции INI файла все еще работают, вам нужно быть осторожными с проблемами Vista. 16-разрядные программы часто сохраняют свой INI файл в системном каталоге Windows.
Это лишь некоторые из проблем, которые я могу вспомнить. Прошло более десяти лет с тех пор, как я портировал Win32. Как только вы попадаете в нее, это довольно быстро. Каждая кодовая база будет иметь свое "чувство", когда дело доходит до переноса, к которому вы привыкнете. Вероятно, вы даже найдете несколько ошибок на этом пути.
Ответ 3
В статье приведено окончательное руководство по Портирование 16-битного кода в 32-разрядную Windows в MSDN.
Ответ 4
В исходном win32 sdk был инструмент, который сканировал исходный код и помеченные строки, которые необходимо было изменить, но я не могу запомнить имя этого инструмента.
Когда мне приходилось это делать в прошлом, я использовал технику грубой силы - то есть:
1 - обновить make файлы или создать среду для использования 32-битного компилятора и компоновщика. Возможно, просто создайте новый проект в своей среде IDE (я использую Visual Studio) и добавлю файлы вручную.
2 - build
3 - исправить ошибки
4 - повторить 2 и 3 до конца
Боль процесса зависит от приложения, которое вы переносите. Я преобразовал 10 000 линейных программ за час и 75 000 линейных программ менее чем за неделю. У меня также были небольшие утилиты, которые я просто сдал и переписал (в основном) с нуля.
Ответ 5
Я согласен с Аланом в том, что проб и ошибок, вероятно, лучший способ.
Вот несколько хороших советы.
Ответ 6
Согласился, что компилятор, вероятно, поймает большинство ошибок. Кроме того, если вы используете "ближние" и "дальние" указатели, вы можете удалить эти обозначения - указатель - это просто указатель в Win32.