Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Совместное использование *.сpp файлов и *.c
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2
kolobochishe
Вот такая ошибка при вызове функции написанной в *.cpp файле из *.с файла

Linking
Error[Li005]: no definition for "plot_spectrum" [referenced from C:\ÐÀÁÎÒÀ\ÐÀÇÐÀÁÎÒÊÈ\ÏÐÎÅÊÒÛ\ÄÐÀÊÎÍ\Ðåãèñòðàòîðû\Ïðîøèâêà\
LPC3250 GUI_RTOS\arm\PowerPac\BoardSupport\NXP\LPC3250\Output\LPC3250\Debug_SDRAM\Obj\DRAGON_BS1_GUI.o]
Error while running Linker

Функция объявлена в соответствующем *.h файле. Он подключен везде, где требуется.
MrYuran
В хедерах си-шных модулей надо вставить скобки
Код
#ifdef __cplusplus
BEGIN_EXTERN_C
#endif
...
#ifdef __cplusplus
END_EXTERN_C
#endif

, где
Код
#define BEGIN_EXTERN_C           extern "C" {
#define END_EXTERN_C             }


Компилировать и линковать в режиме "плюсов"
sergeeff
Проще прямо написать
Код
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
kolobochishe
Цитата(MrYuran @ Jun 9 2011, 12:43) *
В хедерах си-шных модулей надо вставить скобки
Код
#ifdef __cplusplus
BEGIN_EXTERN_C
#endif
...
#ifdef __cplusplus
END_EXTERN_C
#endif

, где
Код
#define BEGIN_EXTERN_C           extern "C" {
#define END_EXTERN_C             }


Компилировать и линковать в режиме "плюсов"


Компилится. Только не в хэдерах си-шных модулей, а в хэдере си++ модуля. У меня только так заработало.
mdmitry
Цитата(kolobochishe @ Jun 9 2011, 12:05) *
Компилится. Только не в хэдерах си-шных модулей, а в хэдере си++ модуля. У меня только так заработало.

Можно ставить с любых заголовочных файлах, которые включаются в проект для с и cpp.
inventor
Цитата(mdmitry @ Jun 9 2011, 13:47) *
Можно ставить с любых заголовочных файлах, которые включаются в проект для с и cpp.

в принципе если извратица то можно из сишной программы вызывать с++ модули.
у вас проблема в том, что С++ делает такую хрень как name mangling.
то есть при линковке имена ваших функций становятся такими что их сишный линкер
не может понять.
решение которое вам подсказали вверху заставляет линкер не искажать имя функции.
но если вы попробуете предложить несколько функций с одинаковым названием-перегруженные,
то опять получите ошибку.
sergeeff
Цитата(inventor @ Jun 16 2011, 22:24) *
в принципе если извратица то можно из сишной программы вызывать с++ модули.


Если вы можете компилировать с++ модули (компилятор позволяет), то никто не мешает сказать ему, чтобы для компиляции .с модулей тоже вызывался С++ компилятор. На худой случай, просто переименовать *.с в *.срр.
zltigo
QUOTE (sergeeff @ Jun 17 2011, 13:24) *
просто переименовать *.с в *.срр.

С и С++ два разных языка - сколь-нибудь объемный и что-то делающий исходник на 'C' (не "Hello World!" ) плюсовым компилятором не откомпилится. Потребуются правки. В большей частью мелкие, но местами и принципиально все меняющие.
sergeeff
Цитата(zltigo @ Jun 17 2011, 16:54) *
С и С++ два разных языка - сколь-нибудь объемный и что-то делающий исходник на 'C' (не "Hello World!" ) плюсовым компилятором не откомпилится. Потребуются правки. В большей частью мелкие, но местами и принципиально все меняющие.


Хоть один пример.
zltigo
QUOTE (sergeeff @ Jun 17 2011, 16:20) *
Хоть один пример.

Берете свой проект, компилите плюсовым. Получаете примеры sm.gif
Сергей Борщ
QUOTE (sergeeff @ Jun 17 2011, 16:20) *
Хоть один пример.
Область видимости констант, неявное приведение void * к любому указателю в С. Это так, навскидку.
Danis
Цитата(sergeeff @ Jun 17 2011, 16:20) *
Хоть один пример.


для С++ NULL не типизирован явно, как в Си, так что приходиться делать так:

/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
zltigo
QUOTE (Сергей Борщ @ Jun 17 2011, 16:40) *
Область видимости констант, неявное приведение void * к любому указателю в С. Это так, навскидку.

Декларация и инициализация стуктур и константных объектов, тип литералов типа 'abcd', объявления типов в sizеof, , функции с переменным количеством аргументов, еще некоторые до сих пор не польззуются прототипами функций sm.gif и C а не C99,..... В общем лучше попробовать компильнуть sm.gif
Вообще-то в С++ стандарте, помнится, было целое приложение посвященное проблемам несовместимости.

P.S.
Да. Посмотрел - Annex C Compability. Единственно, что там явно не C99. Да и многие 'С' компиляторы будут на некоторые конструкции хоть не ошибки, но warnings выдавать.
dxp
Цитата(Сергей Борщ @ Jun 17 2011, 20:40) *
Область видимости констант, неявное приведение void * к любому указателю в С. Это так, навскидку.

Ещё работа с перечислимыми типами.
sonycman
А наоборот может быть - ошибка при вызове из си++ файла функции, объявленной в простом си исходнике?

Ошибка такая же - Li005 - линкер не может найти определение функции... sad.gif
sergeeff
Цитата(sonycman @ Jun 18 2011, 12:38) *
А наоборот может быть - ошибка при вызове из си++ файла функции, объявленной в простом си исходнике?

Ошибка такая же - Li005 - линкер не может найти определение функции... sad.gif


Вы хоть эту ветку читаете? Про extern "C"?
sonycman
Цитата(sergeeff @ Jun 18 2011, 17:51) *
Вы хоть эту ветку читаете? Про extern "C"?

А вы хоть читаете, о чём я спрашиваю?
Одно дело, когда обычный си модуль не может найти си++ функцию, имя которой, по понятным причинам, видоизменено.
Но когда наоборот - си++ модуль в упор не видит обычную си функцию?

В этом случае ведь name mangling не работает?

Ошибка уходит, когда принудительно включаю компиляцию си файлов в режиме си++.
AHTOXA
Цитата(sonycman @ Jun 19 2011, 23:36) *
Но когда наоборот - си++ модуль в упор не видит обычную си функцию?

Именно для этого случая и нужно в заголовочных файлах от си функций писать extern "C". Иначе C++ ожидает функции с замангленными именами.
sonycman
Цитата(AHTOXA @ Jun 19 2011, 22:04) *
Именно для этого случая и нужно в заголовочных файлах от си функций писать extern "C". Иначе C++ ожидает функции с замангленными именами.

Понятно. Значит, всегда, когда плюсы имееют дело с ассемблерными или обычными сишными модулями (или наоборот) необходимо юзать этот костыль.
Спасибо beer.gif
sergeeff
Цитата(sonycman @ Jun 19 2011, 22:14) *
Понятно. Значит, всегда, когда плюсы имееют дело с ассемблерными или обычными сишными модулями (или наоборот) необходимо юзать этот костыль.
Спасибо beer.gif


А это вовсе не костыль, а возможность из С++ использовать С/ASM модули. Вам эта возможность не нравится?

sonycman
Цитата(sergeeff @ Jun 20 2011, 00:30) *
А это вовсе не костыль, а возможность из С++ использовать С/ASM модули. Вам эта возможность не нравится?

Я об этом знал, но считал, что это работает только в сторону от си++ к си.
Не думал, что плюсы будут манглить даже обычную сишную функцию, подключенную через хидер laughing.gif
dxp
Цитата(sonycman @ Jun 20 2011, 04:17) *
Я об этом знал, но считал, что это работает только в сторону от си++ к си.
Не думал, что плюсы будут манглить даже обычную сишную функцию, подключенную через хидер laughing.gif

Если компиляете в С++ режиме, то все функции будут кодироваться по-плюсатому. Ведь в плюсах обычное дело та же перегрузка имён функций, и как компилятор должен догадаться, какие функции у вас имеют С-связывание, а какие С++ связывание. Для этого и введена спецификация связывания extern "<Lang>", где <Lang> - отличный от С++ язык (там не обязательно должен быть С, хотя этот вариант встречается в подавляющем большинстве случаев).
XVR
Цитата(sonycman @ Jun 20 2011, 01:17) *
Не думал, что плюсы будут манглить даже обычную сишную функцию, подключенную через хидер laughing.gif
А откуда С++ знать, что это 'обычная С функция'? Для этого extern "C" и предназначен rolleyes.gif
sonycman
Цитата(dxp @ Jun 20 2011, 06:59) *
Если компиляете в С++ режиме, то все функции будут кодироваться по-плюсатому. Ведь в плюсах обычное дело та же перегрузка имён функций, и как компилятор должен догадаться, какие функции у вас имеют С-связывание, а какие С++ связывание. Для этого и введена спецификация связывания extern "<Lang>", где <Lang> - отличный от С++ язык (там не обязательно должен быть С, хотя этот вариант встречается в подавляющем большинстве случаев).

Спасибо.
Интересно, а какие ещё есть идентификаторы <Lang>?

Цитата(XVR @ Jun 20 2011, 12:42) *
А откуда С++ знать, что это 'обычная С функция'? Для этого extern "C" и предназначен rolleyes.gif

Так тело-то этой функции - в обычном .c файле!
Компилер что, манглит сразу имя функции по её объявлению в хидере, не заглядывая даже в определение?
Вот шустрый какой! biggrin.gif
XVR
Цитата(sonycman @ Jun 20 2011, 13:13) *
Так тело-то этой функции - в обычном .c файле!
А как компилятор в процессе компиляции файла А узнает о теле функции в файле Б? Он же их отдельно компилирует
Цитата
Компилер что, манглит сразу имя функции по её объявлению в хидере, не заглядывая даже в определение?
Разумеется. Тело функции его не интересует (его вообще может не быть)
sonycman
Цитата(XVR @ Jun 20 2011, 13:21) *
Разумеется. Тело функции его не интересует (его вообще может не быть)

Понятно, теперь буду знать. Спасибо! rolleyes.gif
dxp
Цитата(sonycman @ Jun 20 2011, 16:13) *
Интересно, а какие ещё есть идентификаторы <Lang>?

Мне попадалось FORTRAN.
zltigo
QUOTE (dxp @ Jun 20 2011, 14:04) *
Мне попадалось FORTRAN.

И PASCAL

inventor
Кстати, никогда не делайте программы для DSP и контроллеров на С++
выгоды которые вы получите весят меньше чем недостатки и косяки
которые вы встретите и не сможете устранить.
То есть делайте свои программы исключительно на C
а не С++.
Безо всяких "extern C"/
Все таки язык С++ был разработан совсем для других целей.
Ну там базы данных писать и что-то подобное большое.
В качестве системного языка он не подходит.
По моему скромному мнению.
Хотя находятся герои которые для QNX что-то на С++ ваяют.
dxp
Цитата(inventor @ Jun 22 2011, 17:52) *
Кстати, никогда не делайте программы для DSP и контроллеров на С++

sm.gif
Вам сюда.
inventor
Цитата(dxp @ Jun 22 2011, 16:13) *
sm.gif
Вам сюда.


Для меня достаточно просто посмотреть на код С++ в асме-
что он там плодит, чтобы больше так никогда не делать.
Все это красиво получается в исходниках, но не в работе.
AHTOXA
Цитата(inventor @ Jun 22 2011, 16:52) *
Все таки язык С++ был разработан совсем для других целей.
Ну там базы данных писать и что-то подобное большое.
В качестве системного языка он не подходит.
По моему скромному мнению.
Хотя находятся герои которые для QNX что-то на С++ ваяют.
Вот сразу видно - пришёл человек знающий, глубоко разбирающийся в предмете. Всё чётко разложил по полочкам, разоблачил мифы, расписал недостатки, прямо и без обиняков. Теперь мы будем знать, какая кака этот C++. Спасибо вам, уважаемый inventor!
biggrin.gif
dxp
Цитата(inventor @ Jun 22 2011, 20:59) *
Для меня достаточно просто посмотреть на код С++ в асме-
что он там плодит, чтобы больше так никогда не делать.
Все это красиво получается в исходниках, но не в работе.

Заинтриговали. И что же он там такое плодит? Можно пример?
zltigo
QUOTE (dxp @ Jun 22 2011, 17:48) *
Заинтриговали. И что же он там такое плодит?

А, полагаю, все как обычно, например, то, что видит человек сумевший написать 100 команд (условно) на ASM, при виде листинга С/C++ программы хотя-бы на десяток килобайт. А видит он количество команд выходящее за рамки его разумения, вот и все sad.gif. Занавес. Однажды я наблюдал шоковое состояние когда считающемуся достаточно опытным ASM писателю предъявил вместо его программы на ASM, которая,
1) была размером под 8K;
2) генерировала иногда в ответ не такой, сигнал, какой хотел заказчик;
3) не тянула генерацию оного сигнала выше 12KHz (заказчик уже соглашался ставить другой контроллер ).
Сишную, писанную за воскресенье, на пару килобайт меньше, правильно работающую, и к тому-же успевающую где-то под 40KHz работать.
Он думал, а может и сейчас так думает, что его просто дурят прокручивая ему на экране LeCroy какую-то обманку sm.gif. Поскольку доподлинно знал, что С есть гуано sm.gif, поскольку тоже что-то вроде "просто посмотреть на код С++ в асме что он там плодит,"
XVR
Цитата(inventor @ Jun 22 2011, 17:59) *
Для меня достаточно просто посмотреть на код С++ в асме-
что он там плодит, чтобы больше так никогда не делать.
Угу, видели видели. Начинается с воплей 'какое С/С++ гуано', а заканчивается открытием, что у С/С++ компиляторов оказывается есть разные уровни оптимизации и дебаггерные режимы laughing.gif
inventor
Цитата(XVR @ Jun 22 2011, 23:19) *
Угу, видели видели. Начинается с воплей 'какое С/С++ гуано', а заканчивается открытием, что у С/С++ компиляторов оказывается есть разные уровни оптимизации и дебаггерные режимы laughing.gif

код написанный на С++
исполняется дольше кода написанного на С или на asm
хоть ты усрись с оптимизацией
MrYuran
Цитата(inventor @ Jun 23 2011, 15:21) *
код написанный на С++
исполняется дольше кода написанного на С или на asm
хоть ты усрись с оптимизацией

Да и на здоровье.
Ну вот какая, к примеру, разница, находится процессор в IDLE 99% или 98,9% времени?
То же самое в большинстве случаев можно сказать и про объём.
dxp
Цитата(inventor @ Jun 23 2011, 18:21) *
код написанный на С++
исполняется дольше кода написанного на С или на asm
хоть ты усрись с оптимизацией

Это такой закон природы или что? Пример покажите?
inventor
Цитата(dxp @ Jun 23 2011, 16:35) *
Это такой закон природы или что? Пример покажите?

Нет.
Это объективная реальность sm.gif
Сейчас нет под рукой примера, завтра что-нибудь нарою.
XVR
Цитата(inventor @ Jun 23 2011, 15:21) *
код написанный на С++
исполняется дольше кода написанного на С или на asm

Угу, угу. Вспоминается (с баша вроде) -
Цитата
- Вот, моя программа в 10 раз меньше, в 3 раза быстрее и памяти жрет в 5 раз меньше, чем твоя!
- Зато моя работает, а твоя нет.

Желаю успехов в написании программ на ассемблере, ну к примеру, для Itanium'а laughing.gif
Цитата
хоть ты усрись с оптимизацией

Это с опытом обычно проходит 1111493779.gif
sergeeff
Уж сколько понаписано про преждевременную оптимизацию, а воз и ныне там. При программировании на С++, после некоторого периода времени по его освоению и написания собственного прикладного инструментария (библиотек необходимых классов), голова освобождается от необходимости "борьбы с мелочами". Занимаешься собственно решением поставленной задачи, а не поиском какого-нибудь побочного эффекта из-за преобразования указателя к (void *).

Думается уважаемый inventor долго нам будет пример искать.
zltigo
QUOTE (sergeeff @ Jun 24 2011, 13:45) *
Уж сколько понаписано

глупостей
QUOTE
про преждевременную оптимизацию, а ....

Не все правда глупости, но 95% процентов воспринимают подобные речи о "преждевременности" таким образом, что в результате делают глупости sad.gif.

А причем тут преждевременная оптимизация вообще-то???
inventor
Цитата(zltigo @ Jun 24 2011, 17:15) *
глупостей

Не все правда глупости, но 95% процентов воспринимают подобные речи о "преждевременности" таким образом, что в результате делают глупости sad.gif.

А причем тут преждевременная оптимизация вообще-то???


Не было времени сегодня искать пример,
щас попробую его описать.
Процессор работает на чатоте 14 Мгц
обменивается с другим процом на частоте 1Мгц.
На асме около 70 строк кода обработчика прерывания.
На С примерно в два раза больше.
Программа на С работает на пределе.
Но не сбоит.
Даже не представляю как это будет работать на С++.
Да...вся программа умещается во внутренней памяти DSP.
sergeeff
Цитата(zltigo @ Jun 24 2011, 16:15) *
глупостей

Не все правда глупости, но 95% процентов воспринимают подобные речи о "преждевременности" таким образом, что в результате делают глупости sad.gif.

А причем тут преждевременная оптимизация вообще-то???


А что, вопли про громоздкий код С++ по сравнению с С не есть пример "преждевременной оптимизации"? Нет пока не одного реального примера сравнения быстродействия задачи при реализации там и там, а вопли есть. По моему - типичный пример
zltigo
QUOTE (sergeeff @ Jun 25 2011, 11:41) *
А что, вопли про громоздкий код С++ по сравнению с С не есть пример "преждевременной оптимизации"?
....
По моему - типичный пример

После этого я совсем перестал понимать смысл sad.gif вкладываемый Вами в словосочетания "преждевременная оптимизация".
Ну да ладно, переживу.

sergeeff
Цитата(zltigo @ Jun 25 2011, 12:47) *
После этого я совсем перестал понимать смысл sad.gif вкладываемый Вами в словосочетания "преждевременная оптимизация".
Ну да ладно, переживу.


По-моему, вполне понятно о чем идет речь. Заявляется (голословно), что С++ язык медленный, а С и, уж конечно, ASM, намного быстрее. Посему, задача изначально проектируется не на С++. Ровно про это писал Александреску со-товарищи, а именно, сначала сделайте работоспособное решение, а потом, изучайте узкие места и их оптимизируете. Вроде я "мастерам" не противоречу, говоря о "преждевременной оптимизации"-
zltigo
QUOTE (sergeeff @ Jun 25 2011, 19:38) *
Ровно про это писал Александреску со-товарищи, а именно, сначала сделайте работоспособное решение, а потом, изучайте узкие места и их оптимизируете.

Вы опять с этим Александреску с его обобщенно-шаблонно-абстрактным программированием sad.gif.
Нам такие товарищи эмбеддерам совсем НЕ товарищи. Думать о построении системы и узких местах нужно СРАЗУ, а не потом рассматривая что такое выросло и как "оптимизировать" сие ЗАПЛАТКАМИ. Все узкие места должны быть ИЗВЕСТНЫ на этапе проектирования, и сделаны ОЦЕНКИ критичности этих мест до того, как будет написана левой ногой кучи кода.
sergeeff
Цитата(zltigo @ Jun 25 2011, 21:53) *
Вы опять с этим Александреску с его обобщенно-шаблонно-абстрактным программированием sad.gif.
Нам такие товарищи эмбеддерам совсем НЕ товарищи. Думать о построении системы и узких местах нужно СРАЗУ, а не потом рассматривая что такое выросло и как "оптимизировать" сие ЗАПЛАТКАМИ. Все узкие места должны быть ИЗВЕСТНЫ на этапе проектирования, и сделаны ОЦЕНКИ критичности этих мест до того, как будет написана левой ногой кучи кода.


Ну ладно. Александреску нам не авторитет. Мне тоже не все его мысли и рецепты нравятся, хотя встречаются и очень изящные решения. Посмотрим с другой стороны. Имеем в начале работы процессор, компилятор и стандартную библиотеку. Начинаем работать? Начинаем. Прикидываем все, где чего и как по-лучше написать. Сделали. И вдруг (или не вдруг) натыкаемся на то, что стандартная memcpy полная г...о (на форуме мы это неоднократно обсуждали), а мы ее пользуем в хвост и в гриву. Затем выясняется, что и memset такая же. А потом понимаем, что вся куча написана через жо...у. Мы про это тоже СРАЗУ должны были знать на начальном этапе проектирования? Откуда? Нам фирма-изготовитель компилятора "любезно" рассказала?

Вы всегда можете предсказать какой именно алгоритм сортировки окажется самым быстрым на вашем конкретном типе данных? Ой ли.

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

Резюме (мое личное, может и неправильное) - невозможно все заранее предусмотреть (кое что можно), хотя бы из-за ограниченности собственных временнЫх возможностей и сил. Проект всегда итерационен (почти).
Dog Pawlowa
Цитата(sergeeff @ Jun 26 2011, 01:44) *
Проект всегда итерационен (почти).

Не могу согласиться.
Практически во всех проектах можно безболезненно заложить ресурсов в два раза больше, чем требуется при первоначальной оценке.
При некотором отличном от нуля опыте этого вполне хватает, чтобы изменения ТЗ и особенности функционирования семейства контроллеров и/или библиотек уложились в резерв.
inventor
Цитата(sergeeff)
Сделали. И вдруг (или не вдруг) натыкаемся на то, что стандартная memcpy полная г...о (на форуме мы это неоднократно обсуждали), а мы ее пользуем в хвост и в гриву. Затем выясняется, что и memset такая же. А потом понимаем, что вся куча написана через жо...у. Мы про это тоже СРАЗУ должны были знать на начальном этапе проектирования? Откуда? Нам фирма-изготовитель компилятора "любезно" рассказала?


Именно так и есть, обычно все библиотеки САМ перекопилируешь-выкидывая оттуда
все ненужное и исправляя ихние ошибки.
Что в этом неправильного?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.