Не удается открыть источник файл pcap h

Обновлено: 05.07.2024

Установка и использование библиотеки функций захвата сетевых пакетов Libpcap (очень мощная)

1. Введение в Libpcap

Libpcap - это английское сокращение от Packet Capture Libray, то есть библиотеки функций захвата пакетов. Интерфейс функции C, предоставляемый библиотекой, используется для захвата пакетов данных, проходящих через указанный сетевой интерфейс. Интерфейс должен быть установлен на Беспорядочный режим . Об этом упоминается в исходном сокете.

Знаменитая программа TCPDUMP разработана на основе Libpcap. . Функция интерфейса, предоставляемая Libpcap, реализует и инкапсулирует процесс, связанный с перехватом пакетов данных.

Libpcap предоставляет интерфейс захвата сетевых пакетов на уровне пользователя и полностью учитывает переносимость приложения. Libpcap может работать на большинстве платформ Linux. На платформе Windows также есть библиотека разработки с аналогичными функциями: Wincap.

Его работа находится между приложением верхнего уровня и сетевым интерфейсом.

  • Захват пакетов: захват исходных пакетов данных, проходящих через сетевую карту
  • Отправка пользовательского пакета данных: создайте исходный пакет данных в любом формате
  • Сбор и статистика трафика: сбор информации о трафике в сети
  • Фильтрация правил: обеспечьте встроенную функцию фильтрации правил, выберите правила фильтрации по мере необходимости

Он имеет очень широкий спектр приложений. Типичные приложения включают анализаторы протокола Dianluo, генераторы сетевого трафика, системы обнаружения сетевых вторжений, сетевые сканеры и другие инструменты безопасности.

2. установка libpcap

Ссылка для скачивания Libpcap:Нажмите на

Перейдите в каталог загрузки, распакуйте сжатый файл, настройте, скомпилируйте и установите

Если в конфигурации есть ошибка, проверьте, все ли зависимые пакеты у вас установлены. bison, m4, GNU, flex и libpcap-dev (метод установки sudo apt-get ****)

Обратите внимание, что при запуске требуются права root sudo ./***

3. Как работает Libpcap

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

Захват пакета делится на три основные части, включая захват пакетов нижнего уровня, фильтрацию пакетов среднего уровня и пользовательский интерфейс на уровне приложений. Это то же самое, что и в операционной системе Linux для обработки пакетов данных (сетевая карта -> драйвер сетевой карты -> уровень канала данных -> IP-уровень -> транспортный уровень -> приложение). Механизм захвата пакетов заключается в добавлении обработки обхода на уровне канала данных (не мешает обработке собственного стека сетевых протоколов системы). Отправленные и полученные пакеты данных фильтруются и буферизируются через ядро ​​Linux и, наконец, передаются непосредственно в приложение верхнего уровня. программа.

Данный текст является переводом статьи Тима Карстенса Programming with pcap 2002 года. В русскоязычном интернете не так много информации по PCAP. Перевод сделан в первую очередь для людей, которым интересна тема захвата трафика, но при этом они плохо владеют английским языком. Под катом, собственно, сам перевод.

Вступление

Давайте начнем с того, что определим, для кого написана эта статья. Очевидно, что некоторое базовое знание C необходимо (если, конечно, вы не хотите просто понять теорию), для понимания кода приведенного в статье, но вам не нужно быть ниндзя программирования: в тех моментах, которые могут быть понятны только более опытными программистам я постараюсь подробно объяснить все концепции. Так же, пониманию может помочь некоторое базовое знание работы сетей, учитывая что PCAP — это библиотека для реализации сниффинга (Прим. переводчика: Сниффинг — процесс захвата сетевого трафика, своего, или чужого). Все представленные здесь примеры кода были протестированы на FreeBSD 4.3 с ядром по умолчанию.

Начало работы: Общая форма приложения PCAP

Первая вещь которую необходимо понять — общая структура PCAP сниффера. Она может выглядеть следующим образом:

  1. Начнем с определения идентификатора интерфейса, трафик с которого мы хотим получить. В Linux это может быть что нибудь вроде eth0 , в BSD это может быть xl1 , и тому подобное. Мы можем либо указать этот идентификатор в строке, либо попросить PCAP предоставить его нам.
  2. Далее необходимо инициализировать PCAP. На данном этапе нам нужно передать PCAP имя устройства, с которым мы будем работать. При необходимости мы можем захватить трафик с нескольких устройств. Для их различия мы будем использовать дескрипторы сеансов. Так же, как и во время работы с файлами, нам нужно назвать наш сеанс захвата трафика, что бы мы могли отличить его от других подобных сеансов.
  3. В случае, если мы хотим получить какой то определенный трафик (например, только TCP/IP пакеты, или пакеты только с порта 23 и так далее) мы должны создать набор правил, "скомпилировать" их, и применить их к конкретному сеансу. Это трехфазный, тесно связанный процесс. Набор правил изначально находится в строке, а после компилируется в понятный PCAP формат. Компиляция производится вызовом функции внутри нашей программы, она не связана с использованием какого либо внешнего приложения. Далее мы говорим PCAP применить этот фильтр к необходимой нам сессии.
  4. Наконец, мы говорим PCAP начать захват трафика. В случае использования pcap_loop , PCAP будет работать до тех пор, пока не получит столько пакетов, сколько мы ему указали. Каждый раз, когда он получает новый пакет, он вызывает определенную нами функцию. Эта функция может делать все что мы хотим. Она может прочитать пакет, и передать информацию пользователю, она может сохранить его в файл, или вовсе не делать ничего.
  5. После того, как мы закончим работу по захвату, сессию можно закрыть.
    На самом деле это очень простой процесс. Всего пять шагов, один из которых не обязательный (шаг 3). Давайте рассмотрим каждый шаг, и их реализации.

Определение устройства

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

Первый — просто позволить пользователю сказать программе имя того устройства с которого он хочет захватывать трафик. Рассмотрим этот код:

Пользователь определяет устройство указывая его имя в качестве первого аргумента программы. Теперь, строка dev содержит имя интерфейса который мы будем прослушивать в формате понятном PCAP (конечно, при условии, что пользователь дал нам реальное имя интерфейса)

Второй способ также очень прост. Давайте взглянем на программу:

Настройка устройства для сниффинга

Задача создания сессии захвата трафика так же очень проста. Для этого мы будем использовать функцию pcap_open_live() . Прототип этой функции:

Для демонстрации, рассмотрим этот фрагмент кода:

Замечания по поводу разборчивого/неразборчивого режимов сниффинга: два способа очень различны по стилю. Обычно, интерфейс находится в разборчивом режиме, захватывая только тот трафик, который отправлен именно ему. Только трафик направленный от него, к нему, или маршрутизированный через него будет захвачен сниффером. Неразборчивый режим, наоборот, захватывает весь трафик который проходит через кабель. В среде без коммутации это может быть весь сетевой трафик. Очевидным преимуществом этого способа является то, возможно захватить большее количество пакетов, что может быть полезным, или нет, в зависимости от цели захвата трафика. Однако существуют и недостатки. Неразборчивый режим легко детектируется, один узел может четко определить, находится ли другой в неразборчивом режиме или нет. Так же, он работает только в не коммутируемой среде (например хаб, или маршрутизатор использующий APR). Еще одним недостатком является то, что в сетях с большим количеством трафика может не хватить системных ресурсов для захвата и анализа всех пакетов.

Не все устройства предоставляют одни и те же заголовки канального уровня в прочитанных вами пакетах. Ethernet устройства, и некоторые не-Ethernet устройства, могут предоставить Ethernet заголовки, но другие типы устройств, например такие как замыкающие устройства в BSD и OS X, PPP-интерфейсы, и Wi-Fi-интерфейсы в режиме мониторинга — нет.

Вам нужно определить тип заголовков канального уровня, которые предоставляет устройство, и использовать для анализа содержимого пакетов. pcap_datalink() возвращает тип заголовков канального уровня. (Cм. список значений заголовков канального уровня. Возвращаемые значения — значения DHT_ в этом списке)

Если ваша программа не поддерживает заголовки канального уровня предоставляемые устройством, то она должна будет прекратить работу, с помощью подобного кода:

который сработает если устройство не поддерживает Ethernet — заголовки. Это может сработать для кода приведенного ниже, который использует заголовки Ethernet.

Фильтрация трафика

Часто мы заинтересованы в захвате только определенного типа трафика. Для примера — бывает такое, что единственное что мы хотим — это захватить трафик с порта 23(telnet) для поиска паролей. Или возможно мы хотим перехватить файл который был отправлен через порт 21(FTP). Может быть мы хотим захватить только DNS трафик (порт 53 UDP). Однако, бывают редкие случаи, когда мы просто хотим слепо захватывать весь интернет трафик. Давайте рассмотрим функции pcap_compile() и pcap_setfilter() .

Процесс очень простой. После того, как мы вызвали pcap_open_live() и имеем работающую сессию сниффинга, мы можем применить наш фильтр. Вы спросите, почему просто не использовать обычные if / else if выражения? Две причины: первая — фильтр PCAP эффективнее, потому что он фильтрует непосредственно через BPF; соответственно нам нужно куда меньшее количество ресурсов, ведь драйвер BPF делает это напрямую. Вторая — это то, что фильтры PCAP просто проще.

Что бы скомпилировать фильтр мы вызываем функцию pcap_compile() . Прототип определяет эту функцию как:

Первый аргумент — это наш дескриптор сессии ( pcap_t* handle в нашем предыдущем примере). Следующий — это указатель на место, где мы будем хранить скомпилированную версию фильтра. Далее идет само выражение, в обычном строковом формате. После идет целое число, которое определяет, нужно ли оптимизировать выражения фильтра, или нет (0 — нет, 1 — да). Наконец, мы должны определить сетевую маску той сети, к которой мы применяем фильтр. Функция возвращает -1 при ошибке; все остальные значения означают успех.

После компиляции фильтра, время применить его. Вызовем pcap_setfilter() . Следуя нашему формату объяснения PCAP, мы должны рассмотреть прототип этой функции:

Это очень прямолинейно и просто. Первый аргумент — наш дескриптор сессии, второй — указатель на скомпилированную версию нашего фильтра (это должна быть та же переменная, что и в предыдущей функции pcap_compile() ).

Возможно этот пример поможет вам понять лучше:

Пример задания, компиляции и применения PCAP фильтра

Эта программа настроена на сниффинг трафика который проходит через порт 23, в неразборчивом режиме, на устройстве rl0 .

Мы можете заметить, что предыдущий пример содержит функцию, о которой мы еще не говорили. pcap_lookupnet() — это функция которая, получая имя устройства возвращает IPv4 сетевой номер и соответствующую сетевую маску (сетевой номер — это адрес IPv4 ANDed с сетевой маской, поэтому он содержит только сетевую часть адреса). Это существенно, потому что нам нужно знать сетевую маску для применения фильтра.

По моему опыту, этот фильтр не работает в некоторых ОС. В моей тестовой среде я обнаружил, что OpenBSD 2.9 c ядром по умолчанию поддерживает этот тип фильтра, но FreeBSD 4.3 с ядром по умолчанию — нет. Ваш опыт может отличаться.

Реальный сниффинг

На текущем этапе мы узнали как определить устройство, приготовить его для захвата трафика, и применить фильтры. Теперь время захватить несколько пакетов. Есть два основных способа захватывать пакеты. Мы можем просто захватить один пакет, или мы можем войти в цикл, который выполняется пока не будет захвачено n пакетов. Мы начнем с того, что покажем, как можно захватить один пакет, и после рассмотрим методы использования циклов. Взглянем на прототип pcap_next() :

Первый аргумент — дескриптор сессии. Второй — указатель на структуру которая содержит общую информацию о пакете, конкретно — время в которое он был захвачен, длина пакета, и длина его определенной части (например, если он фрагментированный). pcap_next() возвращает u_char указатель на пакет, который описан в структуре. Мы поговорим о чтении пакетов позже.

Это демонстрация использования pcap_next() для захвата пакетов:

Приложение захватывает трафик любого устройства, полученное через pcap_loockupdev() , помещая его в неразборчивый режим. Оно обнаруживает что пакет попадает в порт 23 (telnet) и сообщает пользователю размер пакета (в байтах). Опять же, программа включает в себя вызов pcap_close() , который мы обсудим позже (хотя он вполне понятен).

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

Функция обратного вызова (callback function) не является чем то новым, это обычная вещь в большом количестве API. Концепция, которая стоит за функцией обратного вызова очень проста. Предположим, что у есть программа которая ждет события определенного рода. Просто для примера, предположим что программа ждет нажатие клавиши. Каждый раз, когда пользователь нажимает клавишу, моя программа вызовет функцию, что бы обработать это нажатие клавиши. Это и есть функция обратного вызова. Эти функции используются в PCAP, но вместо вызова их в момент нажатия клавиши, они вызываются тогда, когда PCAP захватывает пакет. Использовать функции обратного вызова можно только в pcap_loop() и pcap_dispatch() которые очень похожи в этом плане. Каждая из них вызывает функцию обратного вызова каждый раз, когда попадется пакет который проходит сквозь фильтр (если конечно фильтр есть. Если нет, то все пакеты, которые были захвачены вызовут функцию обратного вызова).

Прототип pcap_loop() приведен ниже:

Первый аргумент — дескриптор сессии. Дальше идет целое число, которое сообщает pcap_loop() количество пакетов, которые нужно захватить (отрицательное значение говорит о том, что цикл должен выполняться до возникновения ошибки). Третий аргумент — имя функции обратного вызова (только идентификатор, без параметров). Последний аргумент полезен в некоторых приложениях, но в большинстве случаев он просто устанавливается NULL. Предположим, что у нас есть аргументы, которые мы хотим передать функции обратного вызова, в дополнение к тем, которые передает ей pcap_loop() . Последний аргумент как раз то место, где мы это сделаем. Очевидно, вы должны привести их к u_char * типу, что бы убедится что вы получите верные результаты. Как мы увидим позже, PCAP использует некоторые интересные способы передачи информации в виде u_char * . После того, как мы покажем пример того, как PCAP делает это, будет очевидно как сделать это и в этом моменте. Если нет — обратитесь к справочному тексту по С, так как объяснения указателей находятся за рамками темы этого документа. pcap_dispatch() почти идентична в использовании. Единственное различие между pcap_dispatch() и pcap_loop() это то, что pcap_dispatch() будет обрабатывать только первую серию пакетов полученных из системы, тогда как pcap_loop() будет продолжать обработку пакетов или партий пакетов до тех пор пока счетчик не закончится. Для более глубокого обсуждения различий, смотрите официальную документацию PCAP.

Прежде чем мы приведем пример использования pcap_loop() , мы должны проверить формат нашей функции обратного вызова. Мы не можем самостоятельно определить прототип функции обратного вызова, иначе pcap_loop() не будет знать, как использовать ее. Так что мы должны использовать этот формат в качестве прототипа нашей функции обратного вызова:

Давайте разберем его более детально. Первое — функция должна иметь void тип. Это логично, потому что pcap_loop() в любом случае не знал бы, что делать с возвращаемым значением. Первый аргумент соответствует последнему аргументу pcap_loop() . Независимо от того, какое значение передается последним аргументом pcap_loop() , оно передается первому аргументу нашей функции обратного вызова. Второй аргумент — это PCAP заголовок, который содержит информацию о том, когда пакет был захвачен, насколько он большой, и так далее. Структура pcap_pkthdr определена в файле pcap.h как:

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

Но как можно использовать эту переменную (названную packet) в прототипе? Пакет содержит много атрибутов, так что, как можно предположить, это не строка, а набор структур (для примера, пакет TCP/IP содержит в себе Ethernet заголовок, IP заголовок, TCP заголовок, и наконец, данные). Этот u_char указатель указывает на сериализованную версию этих структур. Что бы начать использовать какую нибудь из них необходимо произвести некоторые интересные преобразования типов.

Первое, мы должны определить сами структуры, прежде чем мы сможем привести данные к ним. Следующая структура используется мной для чтения TCP/IP пакета из Ethernet.

Так как в итоге это все относится к PCAP и нашему загадочному u_char указателю? Эти структуры определяют заголовки, которые предшествуют данным пакета. И как мы в итоге можем разбить пакет? Приготовьтесь увидеть одно из самых практичных использований указателей (для всех новичков в С которые думают что указатели бесполезны говорю: это не так).

Опять же, мы будем предполагать, что мы имеем дело с TCP/IP пакетом Ethernet. Этот же метод применяется к любому пакету. Единственное различие — это тип структуры, которые вы фактически используете. Итак, давайте начнем с определения переменных и определения времени компиляции. Нам нужно будет деконструировать данные пакета.

И теперь мы делаем наше магическое преобразование типов:

Как это работает? Рассмотрим структуру пакета в памяти. u_char указатель — просто переменная содержащая адрес в памяти.

Ради простоты, давайте скажем, что адрес на который указывает этот указатель это Х . Тогда, если наши структуры просто находятся в линии, то первая из них — sniff_ethernet , будет расположена в памяти по адресу Х , так же мы можем легко найти адрес структуры после нее. Этот адрес — это Х плюс длина Ethernet заголовка, которая равна 14, или SIZE_ETHERNET .

Аналогично, если у нас есть адрес этого заголовка, то адрес структуры после него — это сам адрес плюс длина этого заголовка. Заголовок IP, в отличие от заголовка Ethernet, не имеет фиксированной длины. Его длина указывается как количество 4-байтовых слов по полю заголовка IP. Поскольку это количество 4-байтных слов, оно должно быть умножено на 4, что бы указать размер в байтах. Минимальная длина этого заголовка составляет 20 байтов.

TCP заголовок так же имеет вариативную длину, эта длина указывается как число 4-байтных слов, в поле "смещения данных" заголовка TCP, и его минимальная длина так же равна 20 байтам.

Итак, давайте сделаем диаграмму:


VARIABLE LOCATION(in bytes)
sniff_ethernet X
sniff_ip X + SIZE_ETHERNET
sniff_tcp X + SIZE_ETHERNET +
payload X + SIZE_ETHERNET + +

sniff_ethernet структура, находясь в первой линии, просто находится по адресу Х . sniff_ip , которая следует прямо за sniff_ethernet , это адрес Х плюс такое количество байтов, которое занимает структура sniff_ethernet (14 байтов или SIZE_ETHERNET ). sniff_tcp находится прямо после двух предыдущих структур, так что его локация это — X плюс размер Ethernet, и IP заголовок. (14 байтов, и 4 раза длина заголовка IP). Наконец, данные (для которых не существует определенной структуры) расположены после них всех.

Итак, на данном этапе мы знаем, как использовать функцию обратного вызова, вызвать ее и получить данные из полученного пакета. Здесь я приложу исходный код готового сниффера. Просто скачайте sniffer.c и попробуйте сами.

Завершение

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

Тим Карстенс 2002. Все права защищены. Распространение и использование, с модификацией и без нее разрешены при соблюдении следующих условий:
Копия должна содержать вышеупомянутое уведомление об авторских правах и этот список условий:
Имя Тима Карстенса не может использоваться для одобрения или продвижения продуктов, полученных из этого документа, без специального предварительного письменного разрешения.

This document is Copyright 2002 Tim Carstens. All rights reserved. Redistribution and use, with or without modification, are permitted provided that the following conditions are met:
Redistribution must retain the above copyright notice and this list of conditions.
The name of Tim Carstens may not be used to endorse or promote products derived from this document without specific prior written permission.
/ Insert 'wh00t' for the BSD license here /

Когда я пытаюсь выполнить установку, происходит следующее:

Я не знаю, где он ищет pcap.h. Я могу подтвердить, что в каталоге pcapy-0.10.8 нет файла с таким именем.

Что я упускаю? Я только что установил WinPcap - мне нужна перезагрузка или что-то еще? Спасибо!

Отредактировано, чтобы добавить. вот вывод из моего журнала установки WinPcap:

Означает ли false s там, что WinPcap не был установлен должным образом? Я надеялся найти pcap.h в моем каталоге WinPcap, но его там нет. Я вижу, где я мог бы добавить дополнительные каталоги файлов include в setup.py, если это необходимо, но я не могу найти pcap.h нигде на моей машине. Откуда я должен это взять?

4 ответа

Я пытаюсь скомпилировать старый проект с помощью VS express 2010, но получаю эту ошибку: фатальная ошибка RC1015: не удается открыть include-файл 'afxres.h'. из этого кода ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource.

Поэтому я целый день пытаюсь интегрировать Boost с Visual Studio (2008) на Windows 7. Я сначала дважды прошел через это, как использовать Boost в Visual Studio 2010 . Я искал все (есть по крайней мере 3 из них) симиральные темы, и ни одна из них не работала. Некоторые люди предлагали использовать.

Из текста на сайте CoreLabs для pcapy следует , что вы загрузили исходный код, а не двоичный файл Win32. Если вам действительно не нужно строить из исходного кода, вам, вероятно, будет проще просто установить двоичный файл LOT .

Означает ли ложь, что WinPcap не был установлен должным образом?

Затем, IF вы NEED для сборки из исходного кода, вам нужно установить пакет разработчика WinPcap . WinPcap - это просто "время выполнения", достаточное для таких программ, как Wireshark, которые уже были созданы, но недостаточное для программного обеспечения, которое использует WinPcap и которое должно быть скомпилировано на вашей машине- и, по-видимому, любой загруженный вами pcapy должен быть построен.

(Это похоже на то, как libpcap упаковывается во многих дистрибутивах Linux - пакет "libpcap" просто устанавливает время выполнения, и вам нужно установить пакет "libpcap-dev" или что-то в этом роде, чтобы получить заголовочные файлы.)

Но если двоичный файл Windows работает для вас, не беспокойтесь о пакете разработчика WinPcap.

Основываясь на ответе Джоша П. (который я только что получил большую часть пути):

  1. загрузите пакет разработчика WinPcap
  2. извлеките файл zip (например, c:\users\foo\Downloads\WpdPack_4_1_2 )
  3. сборка с использованием --global-option для передачи в расположениях заголовка и компоновщика

При указании папки библиотеки для компоновщика на Windows 7 мне нужно было указать версию библиотеки x64, а не версию библиотеки x32 (по умолчанию).:

Я получал следующие ошибки ссылок при использовании версии файла . \lib (x32) :

Как объяснил Гай Харрис, обычно проще загрузить и установить двоичный файл. Если вы строите из исходного кода:

Используйте pip --global-option . setup.py-это другое, но я думаю, что pip в любом случае предпочтительнее setup.py.

Вот пример строки (замените правильные пути для вашей системы; я просто ссылался на них прямо в папке загрузки):

Он даже может определить, нужна ли вам 32-я или 64 bit-я версия этих библиотек.

Предыдущие ответы не помогли мне решить проблему, но помогли мне копать. Так что они могут быть немного устаревшими.

Похожие вопросы:

У меня есть решение visual studio 2010 c++, и есть include, который не удается скомпилировать (фатальная ошибка, не удалось открыть include-файл). Моя проблема в том, что: Путь указан в C/C++.

Я пытаюсь скомпилировать старый проект с помощью VS express 2010, но получаю эту ошибку: фатальная ошибка RC1015: не удается открыть include-файл 'afxres.h'. из этого кода.

Поэтому я целый день пытаюсь интегрировать Boost с Visual Studio (2008) на Windows 7. Я сначала дважды прошел через это, как использовать Boost в Visual Studio 2010 . Я искал все (есть по крайней.

фатальная ошибка C1083: не удается открыть включаемый файл: 'pcap.h': такого файла или каталога нет. Как добавить файл .pcap.h ? Я делаю проект VC++ в 32-битном windows 7

Я начал работать научным сотрудником в своем университете, и мне было поручено разработать компонент для уже существующего приложения, написанного на C++, используя собственный фреймворк, также.

Когда я создаю свое решение на C ++ в Visual Studio, оно жалуется на отсутствие файла xxxxx.pch. Есть ли параметр, который мне не хватает, чтобы вернуть предварительно скомпилированные заголовки?

Вот точная ошибка для полноты:

ПРИМЕЧАНИЕ. Более поздние версии IDE могут использовать «pch» вместо «stdafx» в именах по умолчанию для связанных файлов. В приведенных ниже инструкциях может потребоваться заменить pch на stdafx. Я прошу прощения. Это не моя вина.

  1. Щелкните правой кнопкой мыши свой проект в обозревателе решений.
  2. Щелкните Свойства в нижней части раскрывающегося меню.
  3. В левом верхнем углу страниц свойств выберите в раскрывающемся меню «Все конфигурации».
  4. Откройте дерево C / C ++ и выберите Предварительно скомпилированные заголовки.
  5. Предварительно скомпилированный заголовок: выберите "Использовать" (/ Yu)
  6. Заполните поле Precompiled Header File. Стандарт - stdafx.h

Lucky 13. Скрестите пальцы и нажмите Build.

Я искал файл iOS PCH с той же проблемой, если вы попали сюда, как и я, решение, которое я нашел, - очистить производные данные; Закройте симуляторы, перейдите к параметрам xCode -> местоположения -> перейдите к пути к файлу производных данных, закройте xCode, удалите файлы в папке производных данных, перезапустите и приветствуйте :)

Я знаю, что эта тема очень старая, но недавно я имел дело с этим в VS2015, и что помогло, так это удаление папок сборки и ее повторная сборка. Это могло произойти из-за попытки закрыть программу или из-за остановки / зависания программы VS во время сборки.

Если все верно, но эта ошибка присутствует, необходимо проверить следующий раздел в файле ****. Vcxproj:

В моем случае это было неверное имя конфигурации: только первое слово.

Попробуйте Build> Clean Solution, затем Build> Build Solution. Это работает для меня.

AppCenter запускает команду «pod install» только в том случае, если он находит Pofile и НЕ находит папку PODS в файлах.

У меня была отмечена папка, но поскольку git автоматически игнорирует файлы .pch (проверьте .gitignore, чтобы проверить это), мой .pch не проверялся.

Я решил проблему, заставив файлы .pch проверять ее, но удаление папки PODS тоже должно работать, поскольку в этом случае Appcenter запустит команду установки модуля.

Надеюсь, это кому-то поможет.

  1. Щелкните правой кнопкой мыши проект и выберите пункт меню свойств.
  2. goto C / C ++ -> Предварительно скомпилированные заголовки
  3. Выберите "Не использовать предварительно скомпилированные заголовки"

Убедитесь, что в вашем проекте есть xxxxx.cpp

Скомпилируйте xxxxx.cpp с флагом / Yc ( Создать предварительно скомпилированный заголовок)
(щелкните правой кнопкой мыши xxxxx.cpp -> свойства -> Предварительно скомпилированные заголовки -> создать )

Скомпилируйте все остальные файлы с флагом / Yu ( Используйте предварительно скомпилированный заголовок)
(щелкните правой кнопкой мыши проект -> свойства -> Предварительно скомпилированные заголовки -> использовать )

Использование предварительно скомпилированного заголовка (pch) - это двухэтапный процесс.

На первом этапе вы компилируете файл-заглушку (в VS200x он обычно называется stdafx.cpp . В более новых версиях используется pch.cpp .). Этот файл-заглушка косвенно включает только те заголовки, которые вы хотите предварительно скомпилировать. Обычно в одном небольшом заголовке (обычно stdafx.h или pch.hpp ) перечислены стандартные заголовки, такие как <iostream> и <string> , которые затем включаются в файл-заглушку. При компиляции создается файл .pch.

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

В вашем случае кажется, что шаг 1 не выполняется. Файл-заглушка все еще присутствует? В вашем случае это, вероятно, будет xxxxx.cpp . Это должен быть файл, скомпилированный с помощью /Yc:xxxxx.pch , поскольку это флаг компилятора, указывающий, что это шаг 1 процесса PCH. Если присутствует xxxxx.cpp и является таким файлом-заглушкой, то, вероятно, отсутствует его параметр компилятора /Yc: .

VS облажался (у меня 2019; (). Продолжайте и выберите «не использовать предварительно скомпилированные заголовки», как указывают другие ребята, затем откройте файл проекта (vcxproj) с помощью любого текстового редактора и удалите выделенные две записи в двух местах. Наслаждайтесь На самом деле, запись pch.h в файле vcxproj, которую вы видите ниже, вы всегда найдете в интерфейсах свойств VS.

Читайте также: