Как объединить отдельное приложение c в приложение c ++? - PullRequest
1 голос
/ 23 января 2020

Я работал над приложением C ++ (назовите его recorder.cpp), которое включает в себя некоторые библиотеки C ++ из других источников (которые должны использовать c ++ 14, поэтому я застрял на этом фронте). В настоящее время мое приложение работает, но оно просто выполняет настройку на основе внешних библиотек и аргументов командной строки.

Существует отдельное приложение C (назовите его receiver.c), которое работает независимо, что я в основном хочу совместить с recorder. Я думаю, что простым способом было бы скопировать и вставить все receiver в recorder, но это кажется немного излишним (не говоря уже о том, что если я сделаю моды на receiver в будущем, мне нужно будет затем сделать такие же изменения в recorder). Поэтому я пытался выяснить, есть ли способ связать их, чтобы я мог вызвать receiver из приложения recorder. Я знаю, что я не могу просто вызвать функцию receiver main (), но я не был уверен, есть ли способ построить receiver, чтобы он действовал больше как библиотека, но все же мог быть собран как отдельный приложение.

Ответы [ 2 ]

1 голос
/ 23 января 2020

"... Я пытался выяснить, есть ли способ связать их, чтобы я мог вызвать приемник из приложения рекордера."

Да - но проще Более прямой способ - скопировать код reciever.c (без функции main()) с кодом C ++. Для этого потребуется, чтобы в коде C не было синтаксиса, который нарушал бы правила C++. (Например, приведение к возврату malloc(), например, требуется в C ++, но не рекомендуется в C.) Но поскольку большинство синтаксисов C полностью C++ совместимы, не должно быть никаких изменений или их не требуется. Теперь весь ваш код собран и может быть просто скомпилирован как C++.

Однако подход к компоновке потребует компиляции всех функций вашей автономной программы (опять же, исключив функцию main() в библиотеку. Например, DLL или общая библиотека Эту библиотеку можно связать с помощью заголовочного файла extern "C" { ... } within the C ++, чтобы окружить прототипы функций C, которые определены в файле библиотеки C. Эти функции в окружении будут скомпилированы с использованием связи C вместо C++ Краткий пример:

    // C++ code
    extern "C" void f(int); // one way
    extern "C" {    // another way
        int g(double);
        double h();
    };
    void code(int i, double d)
    {
        f(i);
        int ii = g(d);
        double dd = h();
        // ...
    }  

Воспроизводится отсюда ...

Примечание, включенное в ссылку, это утверждение: "... В дополнение вам нужно прочитать оставшуюся часть этого раздела, чтобы узнать, как сделать так, чтобы ваши C функции вызывались на C ++ и / или ваши функции на C ++ вызывались на C. "

РЕДАКТИРОВАТЬ , чтобы добавить информацию из комментариев:
Относительно создания библиотеки. Затем библиотека может использоваться обеими программами и не поддерживаться в двух местах. Это может усложнить управление версиями, и в будущем могут возникнуть проблемы. s если две программы расходятся в будущем. Также обратите внимание, что возможно использование stati c вместо общей библиотеки. Эти подходы имеют различные значения версий, поскольку в будущем происходят изменения. (из @Avi Berger)

... Или, если вы хотите создать общий файл *. c, чтобы изменения, внесенные для одного приложения, легко включались в другое, вы не делаете библиотека, но просто ссылка в .o файле. (от @Goswin von Brederlow)

0 голосов
/ 23 января 2020

Просто скомпилируйте объектные файлы recorder.o и receiver.o обычным способом. Убедитесь, что у них обоих нет функции main(): либо #ifdef условно, либо (лучше) скомпилируйте ее в свой собственный объектный файл для каждой программы (например, recorder_main.cpp и receiver_main.c).

С этим последним подходом Makefile довольно прост, так как мы можем позволить Make использовать его встроенные правила для правильного создания объектных файлов. Все, что нам нужно сделать, это сказать ему, как связать:

receiver: receiver_main.o receiver.o
        $(LINK.o) $^ $(LDLIBS) -o $@

recorder: recorder_main.o recorder.o receiver.o
        $(LINK.cc) $^ $(LDLIBS) -o $@

Обратите внимание, что нам нужно связать recorder с компоновщиком C ++ (который понимает искажение имени), а не с компоновщиком C.

Если вам нужны отдельные исходные каталоги, это легко сделать с помощью VPATH в Makefile.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...