Как в одном проекте visual studio создать несколько файлов
У меня есть основной исполняемый файл, который запускается на основе настроек, сохраненных в файле конфигурации. Я хочу иметь возможность изменять настройки в файле конфигурации через другой исполняемый файл.
Есть ли простой способ собрать эти два разных исполняемых файла в одном проекте Windows Forms? Это означает, что когда я нажимаю build, в одной папке решения создаются два разных EXE-файла - один, который изменяет файл конфигурации, а другой, который его использует.
Я знаю, что это возможно, если я создам два отдельных проекта, использующих одну и ту же папку решения, но я надеялся сделать все за один шаг.
Я предполагаю, что для этого мне нужен проект с двумя «Основными» функциями. Это возможно?
2 ответа
Вы можете собрать столько сборок в одном решении, сколько захотите. Сборки могут приводить к файлам DLL или EXE.
Создайте решение (или откройте существующее решение).
Щелкните правой кнопкой мыши корневой узел в обозревателе решений, выберите Добавить → Новый проект и выберите тип проекта, который вы хотите добавить.
Щелкните правой кнопкой мыши элемент проекта в обозревателе решений и выберите Свойства → Сборка → Путь вывода . Установите желаемый каталог, в котором он будет построен. Повторите это для других проектов.
Таким образом, в обозревателе решений вы получите следующее:
- MySolution
- MyCommonCode (библиотека классов, в результате получается MyCommonCode.dll)
- MyMainApp (приложение Windows Forms, результат - MyMainApp.exe)
- MyConfigApp (приложение Windows Forms, результат MyConfigApp.exe)
Сборка MyCommonCode содержит общий код, который оба EXE-файла используют как идентификаторы вашего файла конфигурации и т. Д.
MyMainApp - это приложение с графическим интерфейсом (Windows Forms, WPF и т. Д.) Для вашего основного приложения со ссылкой на проект MyComonCode.
MyConfigApp - это приложение с графическим интерфейсом для редактирования значений конфигурации со ссылкой на проект MyCommonCode.
После сборки решения вы получите следующие двоичные файлы: MyCommonCode.dll , MyMainApp.exe и MyConfigApp.exe .
Обновление на основе комментария:
За один запуск компиляции можно построить только один двоичный файл (DLL или EXE) для каждого проекта. Вы можете сделать что-то вроде ответа выше: переместить большую часть кода в общую / базовую DLL и создать два тонких проекта для двух EXE-файлов, которые «настраивают и используют» только центральный общий / базовый файл DLL.
Вы можете создавать разные EXE-файлы на основе одного и того же проекта, используя определения компилятора. Вы даже можете определить свои собственные определения. Но за один запуск компиляции вы можете создать только один двоичный файл (DLL, EXE) для каждого проекта - один или другой, но не оба.
Идея файла конфигурации заключается в том, что вам не нужно создавать несколько исполняемых файлов. ;-)
Вы можете использовать Configuration Manager , чтобы создать новую конфигурацию решения и изменить выходной каталог для этой конфигурации.
По мере того, как программы становятся больше, в целях организации или повторного использования их обычно разделяют на несколько файлов. Одним из преимуществ работы с IDE является то, что они значительно упрощают работу с несколькими файлами. Вы уже знаете, как создавать и компилировать однофайловые проекты. Добавить новые файлы в существующие проекты очень просто.
Лучшая практика
Когда вы добавляете в проект новые файлы исходного кода, давайте им расширение .cpp .
Для пользователей Visual Studio
В Visual Studio кликните правой кнопкой мыши на папке Исходные файлы (Source Files) в окне Обозревателя решений (Solution Explorer) и выберите Добавить (Add) → Создать элемент… (New Item…).
Рисунок 1 – Добавление нового файла в проект в Visual Studio
Убедитесь, что у вас выбран Файл C++ (.cpp). Дайте новому файлу имя, и он будет добавлен в ваш проект.
Рисунок 2 – Создание нового файла в проекте в Visual Studio
Примечание. Если вы создаете новый файл из меню Файл (File), а не из своего проекта в обозревателе решений, новый файл не будет добавлен в ваш проект автоматически. Вам придется добавить его в проект вручную. Для этого кликните правой кнопкой мыши на папке Исходные файлы (Source Files) в окне Обозревателя решений (Solution Explorer) и выберите Добавить (Add) → Существующий элемент (Existing Item), а затем выберите свой файл.
Теперь, когда вы компилируете свою программу, вы должны увидеть, как компилятор перечисляет имя вашего файла при компиляции.
Для пользователей Code::Blocks
В Code::Blocks перейдите в меню File (Файл) и выберите New (Создать) → File… (Файл…).
Рисунок 3 – Создание нового файла в Code::Blocks
В диалоговом окне New from template (Создать из шаблона) выберите C/C++ source (Исходный файл C/C++) и нажмите Go (Перейти).
Рисунок 4 – Создание нового исходного файла C/C++ в Code::Blocks
На этом этапе вы можете увидеть или не увидеть приветствие в диалоговом окне мастера создания исходного файла C/C++. Если да, щелкните Next (Далее).
Рисунок 5 – Диалоговое окно мастера создания исходного файла C/C++
На следующей странице мастера выберите C++ и нажмите Next (Далее).
Рисунок 6 – Выбор языка при создании нового исходного файла в Code::Blocks
Теперь дайте новому файлу имя (не забудьте расширение .cpp ) и выберите все конфигурации сборки. Наконец, выберите Finish (Готово).
Рисунок 7 – Указание имени файла и выбор конфигураций сборки
Теперь, когда вы будете компилировать свою программу, вы должны увидеть, как компилятор перечисляет имя вашего файла по мере компиляции.
Для пользователей GCC/G++
Из командной строки вы можете создать дополнительный файл самостоятельно, используя свой любимый редактор, и дать ему имя. Когда вы компилируете свою программу, вам нужно будет включить в строку компиляции все соответствующие исходные файлы. Например:
где main.cpp и add.cpp – это имена ваших исходных файлов, а main – имя выходного файла.
Пример с несколькими файлами
В уроке «2.6 – Предварительные объявления и определения» мы рассмотрели программу с одним исходным файлом, которая не компилируется:
Когда компилятор достигает вызова функции add в строке 5 в функции main , он не знает, что такое add , потому что мы определили add только в строке 9! Нашим решением было либо переупорядочить функции (поместив сначала add ), либо использовать для add предварительное объявление.
Теперь посмотрим на аналогичную программу из нескольких исходных файлов:
Ваш компилятор может решить сначала скомпилировать либо add.cpp , либо main.cpp . В любом случае main.cpp не скомпилируется, что приведет к той же ошибке компилятора, что и в предыдущем примере:
Причина точно такая же: когда компилятор достигает строки 5 файла main.cpp , он не знает, что такое идентификатор add .
Помните, что компилятор компилирует каждый файл отдельно. Он не знает о содержимом других исходных файлов и не запоминает что-либо, что он видел из ранее скомпилированных исходных файлов. Таким образом, даже если компилятор, возможно, видел определение функции add ранее (если он сначала скомпилировал add.cpp ), он этого не запомнил.
Эта ограниченная видимость и короткая память являются преднамеренными, чтобы файлы могли иметь функции или переменные, у которых одинаковые имена, но которые не конфликтуют друг с другом. В следующем уроке мы рассмотрим пример такого конфликта.
Наши варианты решения здесь такие же, как и раньше: поместить определение функции add перед функцией main или удовлетворить компилятор предварительным объявлением. В этом случае, поскольку функция add находится в другом файле, вариант изменения порядка определений не подходит.
Лучшее решение здесь – использовать предварительное объявление:
main.cpp (с предварительным объявлением):
add.cpp (остается прежним):
Теперь, когда компилятор компилирует main.cpp , он будет знать, что такое идентификатор add , и будет удовлетворен. Линкер соединит вызов функции add в main.cpp с определением функции add в add.cpp .
Используя этот метод, мы можем предоставить файлам доступ к функциям, которые находятся в другом файле.
Попробуйте скомпилировать add.cpp и main.cpp с предварительным объявлением. Если вы получили ошибку линкера, убедитесь, что вы правильно добавили add.cpp в свой проект или строку компиляции.
Что-то пошло не так!
Есть много вещей, которые могут пойти не так, когда вы в первый раз попытаетесь работать с несколькими файлами. Если вы попробовали приведенный выше пример и столкнулись с ошибкой, проверьте следующее:
1. Если вы получаете ошибку компилятора о том, что add не определена в main , вы, вероятно, забыли предварительное объявление для функции add в main.cpp .
2а. … наиболее вероятная причина в том, что add.cpp неправильно добавлен в ваш проект. При компиляции вы должны увидеть в списке компиляции и main.cpp , и add.cpp . Если вы видите только main.cpp , значит add.cpp определенно не компилируется. Если вы используете Visual Studio или Code::Blocks, вы должны увидеть add.cpp в списке в обозревателе решений / на панели проекта в левой части IDE. Если его не видно, кликните на проекте правой кнопкой мыши и добавьте этот файл, а затем попробуйте скомпилировать снова. Если вы компилируете из командной строки, не забудьте включить main.cpp и add.cpp в свою команду компиляции.
2b. … возможно, вы добавили add.cpp не в тот проект.
2c. … возможно, что файл не компилируется или не линкуется. Проверьте свойства файла и убедитесь, что файл настроен для компиляции/линковки. В Code::Blocks компиляция и линковка – это отдельные флажки, которые следует установить. В Visual Studio есть параметр «исключить из сборки» (exclude from build), для которого следует установить значение «нет» или оставить пустым.
Резюме
Когда компилятор компилирует программу из нескольких исходных файлов, он может компилировать эти файлы в любом порядке. Кроме того, он компилирует каждый файл отдельно, не зная, что находится в других файлах.
Мы будем много работать с несколькими файлами, как только перейдем к объектно-ориентированному программированию, поэтому сейчас самое подходящее время, чтобы убедиться, что вы понимаете, как добавлять и компилировать проекты с несколькими файлами.
Напоминание: всякий раз, когда вы создаете новый исходный файл (.cpp), вам нужно будет добавить его в свой проект, чтобы он компилировался.
Как только программы становятся больше, их следует разбивать на несколько файлов (в целях удобства и улучшения функциональности). Одним из преимуществ использования IDE является легкость в работе с n-ным количеством файлов. Мы уже знаем, как создавать и компилировать однофайловые проекты, добавление новых файлов не составит труда.
Многофайловые проекты в Visual Studio
В Visual Studio щелкните правой кнопкой мыши по имени вашего проекта в "Обозревателе решений" , затем "Добавить" > "Создать элемент. " :
Во всплывающем диалоговом окне выберите тип файла, укажите его имя, расположение, а затем нажмите "Добавить" :
Также вы можете добавлять файлы к вашему проекту через "Проект" > "Добавить новый элемент. " :
Многофайловые проекты в Code::Blocks
В Code::Blocks перейдите в "File" > "New" > "File. " :
Затем выберите "C/C++ source" и нажмите "Go" :
Затем "Next" (этого окна может и не быть):
Затем "C++" и опять "Next" :
Затем укажите имя нового файла (не забудьте расширение .cpp) и его расположение (нажмите на троеточие и выберите путь). Убедитесь, что поставлены все три галочки (они отвечают за конфигурации сборки). Затем нажмите "Finish" :
Готово! Файл добавлен.
Многофайловые проекты в GCC/G++
В командной строке вам нужно будет создать файл, указать его имя и подключить к компиляции, например:
g++ main.cpp add.cpp -o main
Пример многофайловой программы
Рассмотрим следующую программу, которая состоит из двух файлов.
std :: cout << "The sum of 3 and 4 is: " << add ( 3 , 4 ) << std :: endl ;Попробуйте запустить эту программу. Она не скомпилируется, вы получите следующую ошибку:
add: идентификатор не найден
При компиляции кода, компилятор не знает о существовании функций, которые находятся в других файлах. Это сделано специально, чтобы функции и переменные с одинаковыми именами, но в разных файлах, не вызывали конфликт имен.
Тем не менее, в данном случае, мы хотим, чтобы main.cpp знал (и использовал) функцию аdd(), которая находится в add.cpp. Для предоставления доступа main.cpp к функциям add.cpp, нам нужно использовать предварительное объявление:
int add ( int x , int y ) ; // это нужно для того, чтобы main.cpp знал, что функция add() определена в другом месте std :: cout << "The sum of 3 and 4 is: " << add ( 3 , 4 ) << std :: endl ;Теперь, когда компилятор будет компилировать main.cpp, он будет знать, что такое add(). Попробуйте запустить эту программу еще раз.
Что-то пошло не так!
Пункт №1: Если вы получили ошибку от компилятора, что функция add() не определена в main(), то, скорее всего, вы забыли записать предварительное объявление функции add() в main.cpp.
Пункт №2: Если вы получили следующую ошибку от линкера:
unresolved external symbol "int __cdecl add(int,int)" (?add@@YAHHH@Z) referenced in function _main
то возможных решений есть несколько:
a) Cкорее всего, add.cpp некорректно добавлен в ваш проект. Если вы используете Visual Studio или Code::Blocks, то вы должны увидеть add.cpp в "Обозревателе решений" в списке файлов вашего проекта или в панели проекта IDE. Если добавленного файла нет, то щелкните правой кнопкой мыши по вашему проекту и добавьте файл, как это показано выше, а затем повторите попытку компиляции вашего проекта.
б) Вполне возможно, что вы добавили add.cpp к другому проекту.
в) Вполне возможно, что добавленный файл не подключен к компиляции/линкингу. Щелкните правой кнопкой мыши по имени вашего добавленного файла и выберите "Свойства" :
Убедитесь, что пункт "Исключен из сборки" оставлен пустым или выбрано значение "Нет" :
Пункт №3: Не следует писать следующую строку в main.cpp:
Наличие этой строки приведет к тому, что компилятор вставит всё содержимое add.cpp непосредственно в main.cpp вместо того, чтобы рассматривать эти файлы как отдельные.
Разделите следующую программу на два файла (main.cpp и input.cpp): main.cpp должен содержать функцию main(), а input.cpp — функцию getInteger().
Помните, что для функции getInteger() вам понадобится предварительное объявление в main.cpp.
Ответ
int getInteger ( ) ; // предварительное объявление функции getInteger() (905 оценок, среднее: 4,87 из 5)
Урок №19. Прототип функции и Предварительное объявление
Комментариев: 50
Я так понимаю, что при включении в главный файл заголовочный файл библиотеки, которые были в заголовочном файле копируются, что только прибавляет веса главному файлу или все же копирует лишь функции?
Здравствуйте. А если у меня функция getInteger() будет определена в 2 и более файлах, то как файл с функцией main() поймет какой именно getInteger() мне требуется?
Я методом тыка уже определил что будет ошибка )
Юрий :Если вы подключите больше одного файла с определением одной и той же функции в проект, то получите ошибку компиляции. Функция определяется 1 раз в 1 файле.
Юрий :Смотрите решение в уроке №7.
Спасибо, Юрий! Замечательные уроки! Получаю удовольствие.. Возникают вопросы.. ищу на сайтах.. нахожу.. Будут посерьёзнее, намерен обращаться, если позволите!
Юрий :Начал изучать С++ для создания игр на Unreal, но там все как то сложно.
Случайно наткнулся на ваши уроки, это же просто чудо какое то)
Спасибо за ваш труд.
Пожалуй накидаю плюсиков в карму автору)Мне кажется стоило также указать что хорошим тоном является написать функцию в <name>.cpp, сделать её объявление в <name>.h, после чего подключить <name.h> в основном файле.
Вместо того чтобы писать объявления функций напрямую.
Первый файл с функцией int getInteger():
Может кто-нибудь знает как это все осуществить при помощи Xcode, или статью какую-нибудь по обучению использования этой среды.
А что сложного в Xcode? Всё по аналогии с VS, но со своими особенностями (если уж на то пошло). Можно нагуглить на крайний случай.
Юрий :Здравствуйте я пишу в андроид с помощью Dcoder и хотел пройти тест в конце этого урока но у меня выдаёт ошибку.
Спасибо за уроки, хороший язык оказывается.
Срочно нужна помощь.
Начал программировать на андроид с приложения Dcoder(c++: GCC compiler 6.3 (знаю, что это неудобно и т. д., но лучше так, чем никак).
С этим уроком получилась зиминка из-за моего не состояния найти способ, как связать несколько файлов именно в этом приложении. Если кто-то что с этим делать, тогда пишите (буду очень благодарен). Автору спасибо за уроки. Всё очень доходчиво написано.Это символ переноса строки, такая управляющая последовательность(и гуглите 🙂 )
Какая же чудесная находка для меня эти уроки) Автору огромное спасибо за проделанную работу за перевод и адаптацию
Юрий : Юрий :Здравствуйте. Как добавлять файлы в Visual Studio 2017 если он на русском. Просто не очень понятно, переводчик не помогает.
Юрий :Тогда я ошибся, и это чудесно =) Прошу прощения. Я не заметил ссылки, привык их искать где-то в аннотации.
Юрий :Ничего, без проблем 🙂
Добрый день! При попытке добавить в функцию, которая находится в отдельном файле, "stdafx.h" компилятор выдаёт ошибку: не удаётся открыть файл включения stdafx.h: No such file or directory. Без stdafx.h всё нормально работает. Visual Studio 2015.
Юрий :Сегодня читала статью с телефона. Очень удобный сайт)
Юрий :Когда пишу файл add.cpp постоянно не идёт,это ж линкер мешает по моему. И что ему не так,когда твою программу скопировал,также всё:
Ошибка LNK2019 ссылка на неразрешенный внешний символ _main в функции "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) add.cpp 1
Юрий :Вы сделали всё как в уроке? Правильно добавили файл? К тому проекту, что нужно?
Почему в VS нужно обязательно подключать библиотеку stdafx.h? Раньше, когда я учился по видеоурокам, я писал программы и без ее подключения. Но конечно есть одно но, я тогда немного изменил параметры создания проекта: поставил галочку на "Empty project" и удалил галочку на "Security Development Lifecycle (SDL) checks ". Может быть это как-то повлияло?
Юрий :Зачем писать названия в VS (например Source Files) на английском, если в VS есть русский язык?
В этой статье рассматривается порядок создания многофайловой сборки и приводится код, иллюстрирующий каждый шаг процедуры.
Создание многофайловой сборки
Скомпилируйте в модули кода все файлы, содержащие пространства имен, на которые имеются ссылки в других модулях сборки. По умолчанию для модулей кода используется расширение NETMODULE.
Предположим, например, что файл Stringer имеет пространство имен myStringer , которое содержит класс с именем Stringer . Класс Stringer содержит метод с именем StringerMethod , который выводит отдельную строку на консоль.
Для компиляции этого кода используйте следующую команду:
Скомпилируйте все другие модули, используя соответствующие параметры компилятора для указания других модулей, на которые имеются ссылки в коде. На этом этапе используется параметр компилятора /addmodule.
В следующем примере модуль кода с именем Client имеет метод точки входа Main , который ссылается на метод в модуле Stringer.dll, созданном на шаге 1.
Для компиляции этого кода используйте следующую команду:
Для создания сборки из двух файлов используются две компиляции:
При создании сборки из двух файлов используется одна компиляция:
Используйте компоновщик сборок (Al.exe) для создания выходного файла, содержащего манифест сборки. Выходной файл содержит справочную информацию для всех модулей или ресурсов, входящих в сборку.
В командной строке введите следующую команду:
al <module name> <module name> … /main: <method name> /out: <file name> /target: <assembly file type>
В этой команде в аргументах имя модуля задаются имена всех модулей, которые будут включены в сборку. В параметре /main: указывается имя метода, являющегося точкой входа сборки. В параметре /out: задается имя выходного файла, содержащего метаданные сборки. В параметре /target: указывается, что сборка является исполняемым файлом консольного приложения (EXE), исполняемым файлом Windows (WIN) или же файлом библиотеки (LIB).
Как только программы становятся больше, их следует разбивать на несколько файлов (в целях удобства и улучшения функциональности). Одним из преимуществ использования IDE является легкость в работе с n-ным количеством файлов. Мы уже знаем, как создавать и компилировать однофайловые проекты, добавление новых файлов не составит труда.
Многофайловые проекты в Visual Studio
В Visual Studio щелкните правой кнопкой мыши по имени вашего проекта в "Обозревателе решений" , затем "Добавить" > "Создать элемент. " :
Во всплывающем диалоговом окне выберите тип файла, укажите его имя, расположение, а затем нажмите "Добавить" :
Также вы можете добавлять файлы к вашему проекту через "Проект" > "Добавить новый элемент. " :
Многофайловые проекты в Code::Blocks
Затем выберите "C/C++ source" и нажмите "Go" :
Затем "Next" (этого окна может и не быть):
Затем укажите имя нового файла (не забудьте расширение .cpp) и его расположение (нажмите на троеточие и выберите путь). Убедитесь, что поставлены все три галочки (они отвечают за конфигурации сборки ). Затем нажмите "Finish" :
Готово! Файл добавлен.
Многофайловые проекты в GCC/G++
В командной строке вам нужно будет создать файл, указать его имя и подключить к компиляции, например:
g++ main.cpp add.cpp -o main
(где main.cpp и add.cpp — это имена файлов с кодом, а main — это имя файла-результата)
Пример многофайловой программы
Рассмотрим следующую программу, которая состоит из двух файлов.
std :: cout << "The sum of 3 and 4 is: " << add ( 3 , 4 ) << std :: endl ;
Попробуйте запустить эту программу. Она не скомпилируется, вы получите следующую ошибку:
add: идентификатор не найден
При компиляции кода, компилятор не знает о существовании функций, которые находятся в других файлах. Это сделано специально, чтобы функции и переменные с одинаковыми именами, но в разных файлах, не вызывали конфликт имен.
Тем не менее, в данном случае, мы хотим, чтобы main.cpp знал (и использовал) функцию аdd(), которая находится в add.cpp. Для предоставления доступа main.cpp к функциям add.cpp, нам нужно использовать предварительное объявление :
int add ( int x , int y ) ; // это нужно для того, чтобы main.cpp знал, что функция add() определена в другом месте
std :: cout << "The sum of 3 and 4 is: " << add ( 3 , 4 ) << std :: endl ;
Теперь, когда компилятор будет компилировать main.cpp, он будет знать, что такое add(). Попробуйте запустить эту программу еще раз.
Что-то пошло не так!
Есть много вещей, которые могут пойти не так, особенно, если вы это делаете в первый раз. Главное — не паниковать:
Пункт №1: Если вы получили ошибку от компилятора, что функция add() не определена в main(), то, скорее всего, вы забыли записать предварительное объявление функции add() в main.cpp.
Пункт №2: Если вы получили следующую ошибку от линкера:
unresolved external symbol "int __cdecl add(int,int)" (?add@@YAHHH@Z) referenced in function _main
то возможных решений есть несколько:
a) Cкорее всего, add.cpp некорректно добавлен в ваш проект. Если вы используете Visual Studio или Code::Blocks, то вы должны увидеть add.cpp в "Обозревателе решений" в списке файлов вашего проекта или в панели проекта IDE. Если добавленного файла нет, то щелкните правой кнопкой мыши по вашему проекту и добавьте файл, как это показано выше, а затем повторите попытку компиляции вашего проекта.
б) Вполне возможно, что вы добавили add.cpp к другому проекту.
в) Вполне возможно, что добавленный файл не подключен к компиляции/линкингу. Щелкните правой кнопкой мыши по имени вашего добавленного файла и выберите "Свойства" :
Читайте также: