реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Как сделать смешанный проект с/с++?
juvf
сообщение Apr 8 2010, 03:24
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 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 в прикреплении архив с этим тестовым проектом.
Прикрепленные файлы
Прикрепленный файл  testcpp.rar ( 8.91 килобайт ) Кол-во скачиваний: 11
 
Go to the top of the page
 
+Quote Post
bseyur
сообщение Apr 8 2010, 04:29
Сообщение #2


Участник
*

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



extern "C" int myCppF(int f)
{
return ~f;
}
Go to the top of the page
 
+Quote Post
juvf
сообщение Apr 8 2010, 04:46
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 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"?
Go to the top of the page
 
+Quote Post
bseyur
сообщение Apr 8 2010, 04:53
Сообщение #4


Участник
*

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



В хидере скобки надо ставить. Вообще это общепринятый стандарт, ассемблерные метки точно также подцепляются...

Код
#ifdef __cplusplus
extern "C" {
#endif

int myCppF(int f);

#ifdef __cplusplus
}
#endif
Go to the top of the page
 
+Quote Post
juvf
сообщение Apr 8 2010, 05:00
Сообщение #5


Профессионал
*****

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



2bseyur
Спасибо, проблема решена!!!
Go to the top of the page
 
+Quote Post
juvf
сообщение Apr 8 2010, 06:08
Сообщение #6


Профессионал
*****

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



В тестовом проекте заработало, а в реальном варнинг остался

Код
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. как-то это можно пролечить?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Apr 8 2010, 08:54
Сообщение #7


неотягощённый злом
******

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



Цитата(juvf @ Apr 8 2010, 10:23) *
Registrar.с - сишный файл, который вызывает startProcessMeasuring() из сипипишного файла measuringRC. как-то это можно пролечить?

Так, к слову...
Что-то у Вас не то в консерватории. ИМХО, такой ситуации быть не должно.
Обычно CPP проект - это надстройка над "СИ-драйверами" и вызовы происходят только в одностороннем порядке CPP модули вызывают СИ функции, а не наоборот.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
juvf
сообщение Apr 8 2010, 11:09
Сообщение #8


Профессионал
*****

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



Цитата
Так, к слову...
Что-то у Вас не то в консерватории. ИМХО, такой ситуации быть не должно.
Обычно CPP проект - это надстройка над "СИ-драйверами" и вызовы происходят только в одностороннем порядке CPP модули вызывают СИ функции, а не наоборот.
ЭЭЭЭ ,,,,,, но у мена не с++ проект ,,,,,,,,,,,, и не совсем понятно почему двунаправленные вызов - это не есть гуд?. У меня СИ проект и я пишу новый файл на с++. естественно что вызов с++ функций будет происходить из си кода, ну и естественно некоторые модули, которые используются в этом новом с++ уже написаны на си. Т.е. вызовы двусторонние.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Apr 8 2010, 12:02
Сообщение #9


неотягощённый злом
******

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



На мой взгляд механизм extern C даёт возможность получить нормальные имена функций (а не __zvls14_qwew_dadada)
и прочие нюансы связанные со способом передачи аргументов для того чтобы получить совместимость с СИ, а обратного механизма нет в природе (ибо СИ и так является подмножеством CPP).
Поищите в google информацию о смешанных проектах. И я уверен, что первой рекомендацией будет поместить main() в CPP модуль, о чём я и толкую.
Вы можете принять эту информацию к сведению, или продолжать идти своим альтернативным путём, быть может тоже ведущим к успеху.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 8 2010, 13:09
Сообщение #10


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 " ", которая именно для этого случая и введена в язык. Иное ее использование (как в примере выше) указывает на кривизну в дизайне.

Если хотите писать на С++ и достичь при этом эффективности, то тут надо углублять знание предмета - лучше всего по книжкам, иначе ничего не получится. Писать на С++ как на С имеет очень мало смысла и тянет за собой много вопросов ввиду гораздо больше сложности С++ по сравнению с С (с чем вы сейчас и столкнулись).


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
XVR
сообщение Apr 9 2010, 07:13
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 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 файл прототип)
Go to the top of the page
 
+Quote Post
juvf
сообщение Apr 9 2010, 09:26
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 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();
}
Go to the top of the page
 
+Quote Post
XVR
сообщение Apr 9 2010, 10:49
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 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);

Для С первый вариант прототипом не считается (второй - считается)
Go to the top of the page
 
+Quote Post
juvf
сообщение Apr 9 2010, 11:09
Сообщение #14


Профессионал
*****

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



Цитата(XVR @ Apr 9 2010, 17:04) *
Вот в него и вставить

Строка 7 должна быть такой
Код
void startProcessMeasuring(void);

Для С первый вариант прототипом не считается (второй - считается)


Всё, проблема решена, варнинги исчезли. Спасибо!
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 7th July 2025 - 02:14
Рейтинг@Mail.ru


Страница сгенерированна за 0.03174 секунд с 7
ELECTRONIX ©2004-2016