Скомпилировать программу на C ++ с зависимостью только от kernel32.dll и user32.dll? - PullRequest
11 голосов
/ 24 января 2011

Я работаю с Visual Studio 2005.

Я хочу скомпилировать простую программу, которая будет работать с любой 32-битной версией Windows, независимо от установленной версии библиотеки времени выполнения c ++.

Эта программа вызовет функции GetModuleHandle и GetProcAddress без каких-либо других вызовов функций, а затем завершит работу, когда код выхода является адресом функции.

Как скомпилировать программу на C ++ с зависимостью только от kernel32.dll и user32.dll, без какой-либо библиотеки времени выполнения c ++?

Ответы [ 5 ]

5 голосов
/ 24 января 2011

Вам нужно будет указать собственную точку входа вместо использования main или WinMain.Ваша точка входа - пустая функция, не имеющая аргументов.Вы должны указать его имя для компоновщика с помощью /entry:funcName (где funcName заменяется тем именем, которое вы дали функции, которую вы хотите использовать в качестве точки входа).

Когда вы сделаете это, вытакже необходимо указать подсистему для компоновщика, как в /subsystem:console.Обычно он выводит подсистему на основе имени функции, которую находит (например, main -> console, WinMain -> Windows), но когда вы используете свою собственную точку входа, вы должны указать ее явно.Хотя вы, вероятно, не хотите этого делать очень часто, вы можете указать подсистему явно, даже если вы не указали свою собственную точку входа, поэтому (например) вы можете использовать main в качестве точки входа в программу подсистемы Windows,или WinMain в качестве точки входа в консольную программу.

5 голосов
/ 24 января 2011

Установите /NODEFAULTLIB в настройках вашего проекта. В более новых версиях Visual C ++ вам также придется отключать проверки переполнения стека, поскольку они заставляют компилятор автоматически вставлять вызовы библиотечных функций.

РЕДАКТИРОВАТЬ: Если вы действительно имеете в виду «запуск на ЛЮБОЙ 32-битной версии Windows», вам также придется использовать editbin для изменения поля версии подсистемы в заголовке PE. В противном случае вы ограничены (IIRC) Windows 2000 и более поздними версиями при компоновке с компоновщиком VC ++ 2005, а более новые версии VC ++ еще хуже (по умолчанию требуется XP). Windows 2000 - 5.0, вам нужно указать 3.5 или около того, чтобы разрешить все версии NT в дополнение к Win9x.

1 голос
/ 25 января 2011

Я не уверен, почему все не советуют использовать стандартную библиотеку . Этот метод предполагает, что вы хотите, чтобы ваш код работал в Windows 2000 или более поздней версии, и не против потерять поддержку Win 9x. Вы по-прежнему можете использовать стандартную библиотеку C / C ++ - вы можете использовать опцию /MT на страницах генерации кода C / C ++ вашего проекта, которые будут статически ссылаться в стандартной библиотеке.

Однако, два замечания, первое от меня: идея наличия динамически связанной стандартной библиотеки заключается в том, что любые ошибки в ней будут исправляться Центром обновления Windows (теоретически). Если вы статически связываете библиотеку, вам нужно перераспределить ваше приложение, чтобы исправить стандартные ошибки библиотеки. Так что это не рекомендуется.

Во-вторых, из статьи MSDN о опциях компилятора :

Внимание Не смешивайте статические и динамические версии времени выполнения библиотеки. Наличие более одной копии библиотек времени выполнения в процессе может вызвать проблемы, потому что статический данные в одной копии не передаются другая копия. Компоновщик мешает вы от связывания со статическими и динамические версии в одном файле .exe, но вы все равно можете в конечном итоге с двумя (или подробнее) копии времени выполнения библиотеки. Например, динамическая ссылка библиотека связана со статическим (не DLL) версии времени выполнения библиотеки могут вызвать проблемы при использовании с файлом .exe, который был связан с динамическая (DLL) версия библиотеки времени выполнения. (Вы должны также избегать смешивания отладки и неотладки версии библиотек в одном процесс.)

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

Конечно, другим недостатком является то, что это также увеличит размер вашего исполняемого файла.

Редактировать: результат в зависимости от.exe выглядит следующим образом: (конечно, я использую 64-битную Windows, которая доступна только для XP и более поздних версий ... если вы хотите знать, как это выглядит в 32-битных окнах представьте, если бы 64 не было!).

depends.exe program showing only one dynamic dependency, kernel32.dll

0 голосов
/ 25 января 2011

На самом деле вам также не нужен User32.dll, единственные, которые вы действительно не можете удалить, это Kernel32.dll и Ntdll.dll - они внедряются в ваше пространство процесса с помощью PsCreateProcess (то есть, половина того, как ядро ​​создаетновый процесс).

0 голосов
/ 25 января 2011

Проверьте крошечные библиотеки. Также статически ссылка.

...