Перейти к содержанию
    

Как сделать смешанный проект с/с++?

есть проект на си для 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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"?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

#ifdef __cplusplus
extern "C" {
#endif

int myCppF(int f);

#ifdef __cplusplus
}
#endif

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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. как-то это можно пролечить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Registrar.с - сишный файл, который вызывает startProcessMeasuring() из сипипишного файла measuringRC. как-то это можно пролечить?

Так, к слову...

Что-то у Вас не то в консерватории. ИМХО, такой ситуации быть не должно.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так, к слову...

Что-то у Вас не то в консерватории. ИМХО, такой ситуации быть не должно.

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

ЭЭЭЭ ,,,,,, но у мена не с++ проект ,,,,,,,,,,,, и не совсем понятно почему двунаправленные вызов - это не есть гуд?. У меня СИ проект и я пишу новый файл на с++. естественно что вызов с++ функций будет происходить из си кода, ну и естественно некоторые модули, которые используются в этом новом с++ уже написаны на си. Т.е. вызовы двусторонние.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На мой взгляд механизм extern C даёт возможность получить нормальные имена функций (а не __zvls14_qwew_dadada)

и прочие нюансы связанные со способом передачи аргументов для того чтобы получить совместимость с СИ, а обратного механизма нет в природе (ибо СИ и так является подмножеством CPP).

Поищите в google информацию о смешанных проектах. И я уверен, что первой рекомендацией будет поместить main() в CPP модуль, о чём я и толкую.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ЭЭЭЭ ,,,,,, но у мена не с++ проект ,,,,,,,,,,,, и не совсем понятно почему двунаправленные вызов - это не есть гуд?.

У меня СИ проект и я пишу новый файл на с++. естественно что вызов с++ функций будет происходить из си кода, ну и естественно некоторые модули, которые используются в этом новом с++ уже написаны на си. Т.е. вызовы двусторонние.

В С++ производится кодирование внутренних имен (манглинг), что позволяет, в частности, реализовывать перегрузку имен функций и иметь контроль типов на этапе линковки. В С ничего этого нет, имена идут, как есть. Если вы из С кода будете обращаться к ресурсу, описанному на С++, то линкер просто не найдет имени и сообщит вам об ошибке. Поэтому все вызовы С++ функций из С кода придется делать через обертки extern "C":

 

// C++ code
void cpp_fun() { ... }

extern "C" cpp_fun_wrapper() { cpp_fun(); }

// C code


void f()
{
    cpp_fun(); // ошибка - линкер не найдет имени при разрешении связей

    cpp_fun_wrapper();  // правильно, но возможно будут накладные расходы
}

В любом случае тут достаточно гемора. И нет никакого смысла делать такой смешанный код. Либо пишите все на голом С, либо, если уж взяли плюсы, то на них. Иногда при разработке на С++ возникает необходимость в использовании кода, написанного на другом языке, тут на помощь приходит директива extern " ", которая именно для этого случая и введена в язык. Иное ее использование (как в примере выше) указывает на кривизну в дизайне.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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 файл прототип)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В файле 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();
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не понял что куда вставить?

 

вот хидер 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);

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот в него и вставить

 

Строка 7 должна быть такой

void startProcessMeasuring(void);

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

 

Всё, проблема решена, варнинги исчезли. Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...