juvf 17 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба есть проект на си для IAR MSP430. создал новый файл. скомпелял - всё работает. указал опцию новому файлу с++. перестало собиратся. Вообщем не возможно из сишных файлов вызвать функции написанные в с++ файлах. для теста написал маленький проект main.c #include "io430.h" #include "test.h" int main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; int b; b = myCppF(56); return b; } test.h int myCppF(int f); test.cpp #include "test.h" int myCppF(int f) { return ~f; } опции всего проекта и main.c - си, test.cpp - си++. при компиляции ошибка линкера Error[e46]: Undefined external "myCppF" referred in main ( D:\Work\testcpp\Debug\Obj\main.r43 ) Error while running Linker Как вызвать из сишного файла функцию, определённую в с++? ps в прикреплении архив с этим тестовым проектом. testcpp.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bseyur 0 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба extern "C" int myCppF(int f) { return ~f; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба extern "C" int myCppF(int f) { return ~f; } Не плучилось (( Если только в файле test.cpp написать"extern "C" int myCppF(int f) ..." - то выскакивает ошибка Error[Pe337]: linkage specification is incompatible with previous "myCppF" (declared at line 2 of "D:\Work\testcpp\test.h") D:\Work\testcpp\test.cpp 4 если объявить в test.h так же extern "C" int myCppF(int f); Error[Pe040]: expected an identifier D:\Work\testcpp\test.h 2 Warning[Pe223]: function "myCppF" declared implicitly D:\Work\testcpp\main.c 11 Error while running C/C++ compiler test.cpp Где и как конкретно применить extern "C"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bseyur 0 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба В хидере скобки надо ставить. Вообще это общепринятый стандарт, ассемблерные метки точно также подцепляются... #ifdef __cplusplus extern "C" { #endif int myCppF(int f); #ifdef __cplusplus } #endif Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба 2bseyur Спасибо, проблема решена!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба В тестовом проекте заработало, а в реальном варнинг остался Warning[w6]: Type conflict for external/entry "startProcessMeasuring", in module Registrar against external/entry in module measuringRC; prototyped function vs K&R function Registrar.с - сишный файл, который вызывает startProcessMeasuring() из сипипишного файла measuringRC. как-то это можно пролечить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба Registrar.с - сишный файл, который вызывает startProcessMeasuring() из сипипишного файла measuringRC. как-то это можно пролечить? Так, к слову... Что-то у Вас не то в консерватории. ИМХО, такой ситуации быть не должно. Обычно CPP проект - это надстройка над "СИ-драйверами" и вызовы происходят только в одностороннем порядке CPP модули вызывают СИ функции, а не наоборот. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба Так, к слову... Что-то у Вас не то в консерватории. ИМХО, такой ситуации быть не должно. Обычно CPP проект - это надстройка над "СИ-драйверами" и вызовы происходят только в одностороннем порядке CPP модули вызывают СИ функции, а не наоборот. ЭЭЭЭ ,,,,,, но у мена не с++ проект ,,,,,,,,,,,, и не совсем понятно почему двунаправленные вызов - это не есть гуд?. У меня СИ проект и я пишу новый файл на с++. естественно что вызов с++ функций будет происходить из си кода, ну и естественно некоторые модули, которые используются в этом новом с++ уже написаны на си. Т.е. вызовы двусторонние. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба На мой взгляд механизм extern C даёт возможность получить нормальные имена функций (а не __zvls14_qwew_dadada) и прочие нюансы связанные со способом передачи аргументов для того чтобы получить совместимость с СИ, а обратного механизма нет в природе (ибо СИ и так является подмножеством CPP). Поищите в google информацию о смешанных проектах. И я уверен, что первой рекомендацией будет поместить main() в CPP модуль, о чём я и толкую. Вы можете принять эту информацию к сведению, или продолжать идти своим альтернативным путём, быть может тоже ведущим к успеху. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 65 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба ЭЭЭЭ ,,,,,, но у мена не с++ проект ,,,,,,,,,,,, и не совсем понятно почему двунаправленные вызов - это не есть гуд?. У меня СИ проект и я пишу новый файл на с++. естественно что вызов с++ функций будет происходить из си кода, ну и естественно некоторые модули, которые используются в этом новом с++ уже написаны на си. Т.е. вызовы двусторонние. В С++ производится кодирование внутренних имен (манглинг), что позволяет, в частности, реализовывать перегрузку имен функций и иметь контроль типов на этапе линковки. В С ничего этого нет, имена идут, как есть. Если вы из С кода будете обращаться к ресурсу, описанному на С++, то линкер просто не найдет имени и сообщит вам об ошибке. Поэтому все вызовы С++ функций из С кода придется делать через обертки extern "C": // C++ code void cpp_fun() { ... } extern "C" cpp_fun_wrapper() { cpp_fun(); } // C code void f() { cpp_fun(); // ошибка - линкер не найдет имени при разрешении связей cpp_fun_wrapper(); // правильно, но возможно будут накладные расходы } В любом случае тут достаточно гемора. И нет никакого смысла делать такой смешанный код. Либо пишите все на голом С, либо, если уж взяли плюсы, то на них. Иногда при разработке на С++ возникает необходимость в использовании кода, написанного на другом языке, тут на помощь приходит директива extern " ", которая именно для этого случая и введена в язык. Иное ее использование (как в примере выше) указывает на кривизну в дизайне. Если хотите писать на С++ и достичь при этом эффективности, то тут надо углублять знание предмета - лучше всего по книжкам, иначе ничего не получится. Писать на С++ как на С имеет очень мало смысла и тянет за собой много вопросов ввиду гораздо больше сложности С++ по сравнению с С (с чем вы сейчас и столкнулись). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 9 апреля, 2010 Опубликовано 9 апреля, 2010 · Жалоба В тестовом проекте заработало, а в реальном варнинг остался Warning[w6]: Type conflict for external/entry "startProcessMeasuring", in module Registrar against external/entry in module measuringRC; prototyped function vs K&R function Registrar.с - сишный файл, который вызывает startProcessMeasuring() из сипипишного файла measuringRC. как-то это можно пролечить? В файле measuringRC отсуствует прототип функции startProcessMeasuring. Добавьте соотвествующий .h файл (или добавьте В соотвествующий .h файл прототип) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 9 апреля, 2010 Опубликовано 9 апреля, 2010 · Жалоба В файле measuringRC отсуствует прототип функции startProcessMeasuring. Добавьте соотвествующий .h файл (или добавьте В соотвествующий .h файл прототип) не понял что куда вставить? вот хидер measuringRC.h #ifndef MEASURINGRC_H #define MEASURINGRC_H #ifdef __cplusplus extern "C" { #endif void startProcessMeasuring(); #ifdef __cplusplus } #endif // __cplusplus #endif //MEASURINGRC_H вот файл с определением measuringRC.cpp на с++ #include "measuringRC.h" #include "Main.h" #include "UartR.h" void startProcessMeasuring() { //code } вот сишный файлы который вызывает startProcessMeasuring() #include "Main.h" #include "measuringRC.h" void fun(void) { startProcessMeasuring(); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 9 апреля, 2010 Опубликовано 9 апреля, 2010 · Жалоба не понял что куда вставить? вот хидер measuringRC.h Вот в него и вставить #ifndef MEASURINGRC_H #define MEASURINGRC_H #ifdef __cplusplus extern "C" { #endif void startProcessMeasuring(); #ifdef __cplusplus } #endif // __cplusplus #endif //MEASURINGRC_H Строка 7 должна быть такой void startProcessMeasuring(void); Для С первый вариант прототипом не считается (второй - считается) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 9 апреля, 2010 Опубликовано 9 апреля, 2010 · Жалоба Вот в него и вставить Строка 7 должна быть такой void startProcessMeasuring(void); Для С первый вариант прототипом не считается (второй - считается) Всё, проблема решена, варнинги исчезли. Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться