Поясните фрагмент кода #pragma comment

95
30 сентября 2019, 20:10

в VS2008 создал из шаблона MFC проект. Все работает. Далее подключаю стороннюю dll. Компиляция проходит успешно. Однако, при запуске приложения ругается на отсутствие MSVCP90.dll. Поиск показал, что такие файлы находятся в подпапках каталога C:\Windows\winsxs. Аналогично и в C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist. Методом "научного тыка" из примера (вроде как был создан в VS2008), поставляемого с подключаемой dll, скопировал в проект кусок кода:

#ifdef _DEBUG
#ifdef _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' "            
    "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' "              
    "version='" _CRT_ASSEMBLY_VERSION "' "                          
    "processorArchitecture='x86' "                                  
    "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#pragma comment(linker,"/manifestdependency:\"type='win32' "        
    "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "              
    "version='" _MFC_ASSEMBLY_VERSION "' "                          
    "processorArchitecture='x86' "                                  
    "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' "            
    "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' "              
    "version='" _CRT_ASSEMBLY_VERSION "' "                          
    "processorArchitecture='amd64' "                                
    "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#pragma comment(linker,"/manifestdependency:\"type='win32' "        
    "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "              
    "version='" _MFC_ASSEMBLY_VERSION "' "                          
    "processorArchitecture='amd64' "                                
    "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#endif
#endif

и все заработало.

  1. Почему без этого кода exe-шник не может найти нужные dll?
  2. Где в проекте определяются директивы #ifdef _DEBUG и #ifdef _M_IX86, что условие становится истинным? Где-то в свойствах проекта?
  3. Поясните суть этого кода. И как оно влияет на поиск нужной dll. В книге не помню, что бы такое писали. Или дайте ссылку, где хорошо об этом написано.
  4. Если создавать аналогичный MFC проект в VS2010, что с данным куском кода, что без, ругается на отсутствие MSVCP90.dll. Заметил, если создать проект в VS2008 c данным куском кода. Затем открыть его в VS2010 и в настройках поставить Platform toolset v90, то работает. Как, изначально создавая проект в VS2010, указать на эту dll?

Спасибо.

Answer 1

Есть такая штука как "предварительно объявленные (добавленные) определения". Ваши два как раз к таким относятся.

  • _DEBUG Определен как 1 когда добавлены опции компилятора /LDd, /MDd, или/MTd.Иначе - не определен.
  • _M_IX86 Определен как число со значением 600 если компилируется для x86 процессора. Этот макрос не определен для платформы x64 или ARM.

Это был ответ на второй вопрос.

#pragma comment - это очень многофункциональная штука. В данном случае она позволяет передать опции линковщику. А остальное - просто обвязка, что бы сформировать правильное.

Это был ответ на третий вопрос.

В данном случае эти строки формируют специальный файл-манифест, куда добавляет разные подсказки для загрузчика PE файлов (то есть, ехе файлов).

Почему все это нужно? в свое время, Майкрософт наткнулась на проблему под названием "dll hell" (кошмары с dll) - когда есть несколько длл, разных версий, которые работают немного по разному. И, программисты (плохие программисты), зная об этом, обязательно тащат с собой "правильные dll" и копируют их в папку windows (а то держать у себя в папке как то не серьезно). Майкрософт, почесала репу и придумала штуку под названием side by side, она же SxS, она же "бок о бок". Если приложению нужны стандартные длл специфических версий, то их ему предоставят, подсунув правильные. А что бы Windows знала что нужно, для этого есть файл манифеста. Это ответ на первый вопрос.

В какой книге написано? о, это хороший вопрос. Обычно такое пишут на msdn.com - потому что это не часть стандарта, а вещи, специфические для конкретного компилятора.

READ ALSO
QSettings Обработка данных и работа с реестром

QSettings Обработка данных и работа с реестром

Всем приветУ меня есть текстовый редактор

151
E/SQLiteLog: (1) near “=”: syntax error [закрыт]

E/SQLiteLog: (1) near “=”: syntax error [закрыт]

я уже с ума схожу где то = не так стоит, хееелп

223
Если в базе поле заполнено как text, то вывести текст, если цифры, то вывести цифры

Если в базе поле заполнено как text, то вывести текст, если цифры, то вывести цифры

Возникла проблема, сейчас пользователи могут заполнить поле как цифрами так и не заполнять его вообще (заполнится автоматически текстом)

97