|
|
  |
Как сделать смешанный проект с/с++? |
|
|
|
Apr 8 2010, 03:24
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
есть проект на си для 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 в прикреплении архив с этим тестовым проектом.
|
|
|
|
|
Apr 8 2010, 04:29
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 8-01-07
Из: Томск
Пользователь №: 24 208

|
extern "C" int myCppF(int f) { return ~f; }
|
|
|
|
|
Apr 8 2010, 04:46
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(bseyur @ Apr 8 2010, 10:44)  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"?
|
|
|
|
|
Apr 8 2010, 04:53
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 8-01-07
Из: Томск
Пользователь №: 24 208

|
В хидере скобки надо ставить. Вообще это общепринятый стандарт, ассемблерные метки точно также подцепляются... Код #ifdef __cplusplus extern "C" { #endif
int myCppF(int f);
#ifdef __cplusplus } #endif
|
|
|
|
|
Apr 8 2010, 08:54
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(juvf @ Apr 8 2010, 10:23)  Registrar.с - сишный файл, который вызывает startProcessMeasuring() из сипипишного файла measuringRC. как-то это можно пролечить? Так, к слову... Что-то у Вас не то в консерватории. ИМХО, такой ситуации быть не должно. Обычно CPP проект - это надстройка над "СИ-драйверами" и вызовы происходят только в одностороннем порядке CPP модули вызывают СИ функции, а не наоборот.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Apr 8 2010, 11:09
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата Так, к слову... Что-то у Вас не то в консерватории. ИМХО, такой ситуации быть не должно. Обычно CPP проект - это надстройка над "СИ-драйверами" и вызовы происходят только в одностороннем порядке CPP модули вызывают СИ функции, а не наоборот. ЭЭЭЭ ,,,,,, но у мена не с++ проект ,,,,,,,,,,,, и не совсем понятно почему двунаправленные вызов - это не есть гуд?. У меня СИ проект и я пишу новый файл на с++. естественно что вызов с++ функций будет происходить из си кода, ну и естественно некоторые модули, которые используются в этом новом с++ уже написаны на си. Т.е. вызовы двусторонние.
|
|
|
|
|
Apr 8 2010, 13:09
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(juvf @ Apr 8 2010, 18:24)  ЭЭЭЭ ,,,,,, но у мена не с++ проект ,,,,,,,,,,,, и не совсем понятно почему двунаправленные вызов - это не есть гуд?. У меня СИ проект и я пишу новый файл на с++. естественно что вызов с++ функций будет происходить из си кода, ну и естественно некоторые модули, которые используются в этом новом с++ уже написаны на си. Т.е. вызовы двусторонние. В С++ производится кодирование внутренних имен (манглинг), что позволяет, в частности, реализовывать перегрузку имен функций и иметь контроль типов на этапе линковки. В С ничего этого нет, имена идут, как есть. Если вы из С кода будете обращаться к ресурсу, описанному на С++, то линкер просто не найдет имени и сообщит вам об ошибке. Поэтому все вызовы С++ функций из С кода придется делать через обертки extern "C": Код // C++ code void cpp_fun() { ... }
extern "C" cpp_fun_wrapper() { cpp_fun(); }
// C code
void f() { cpp_fun(); // ошибка - линкер не найдет имени при разрешении связей
cpp_fun_wrapper(); // правильно, но возможно будут накладные расходы } В любом случае тут достаточно гемора. И нет никакого смысла делать такой смешанный код. Либо пишите все на голом С, либо, если уж взяли плюсы, то на них. Иногда при разработке на С++ возникает необходимость в использовании кода, написанного на другом языке, тут на помощь приходит директива extern " ", которая именно для этого случая и введена в язык. Иное ее использование (как в примере выше) указывает на кривизну в дизайне. Если хотите писать на С++ и достичь при этом эффективности, то тут надо углублять знание предмета - лучше всего по книжкам, иначе ничего не получится. Писать на С++ как на С имеет очень мало смысла и тянет за собой много вопросов ввиду гораздо больше сложности С++ по сравнению с С (с чем вы сейчас и столкнулись).
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Apr 9 2010, 07:13
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(juvf @ Apr 8 2010, 10:23)  В тестовом проекте заработало, а в реальном варнинг остался Код 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 файл прототип)
|
|
|
|
|
Apr 9 2010, 09:26
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата В файле 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(); }
|
|
|
|
|
Apr 9 2010, 10:49
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(juvf @ Apr 9 2010, 13:41)  не понял что куда вставить?
вот хидер 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); Для С первый вариант прототипом не считается (второй - считается)
|
|
|
|
|
Apr 9 2010, 11:09
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(XVR @ Apr 9 2010, 17:04)  Вот в него и вставить Строка 7 должна быть такой Код void startProcessMeasuring(void); Для С первый вариант прототипом не считается (второй - считается) Всё, проблема решена, варнинги исчезли. Спасибо!
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|