Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Структура проекта С++, Linking ERROR: multiple definition 
:(
    Опции темы
Gwendolen
Дата 19.10.2006, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 5.4.2005

Репутация: нет
Всего: 1



Пожалуйса помогите разобраться с структурой сложного проекта.

Чтобы вечно не писать #ifdef _EXTRABUILD ... #endif, я создал заголовочный файл со следующей структурой 

extra.h:
Код

#ifndef EXTRA_H_
#define EXTRA_H_

#ifdef _EXTRABUILD

void _mes(LPCTSTR MyParam)
  {
    MessageBox(NULL, MyParam, L"EXTRABUILD", MB_OK);
  }

#define _extra_func(Param) _mes(Param)

#else // _EXTRABUILD

#define _extra_func(Param)

#endif // _EXTRABUILD

/*
#else // EXTRA_H_

#ifdef _EXTRABUILD

void _mes(LPCTSTR MyParam);

#define _extra_func(Param) _mes(Param)

#else // _EXTRABUILD

#define _extra_func(Param)

#endif // _EXTRABUILD
*/

#endif //EXTRA_H_


Если использовать в одном модуле то все ОК:

prjmain.cpp
Код

...
#include "extra.h"
#include "modules\sam_other.h"
...

int APIENTRY
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  {
    ...
    _extra_func(L"MES MAIN");
    ...
  }


А если подключить в sam_other.cpp

Код

#include "..\extra.h"
...
_extra_func(L"MES MODULE"); // Где-то в коде
...


то  линкер то ругается на multiple definition of `_mes(wchar_t const*)' smile 

_EXTRABUILD задается глобально в настройках компилятора.

Вопрос в следующем: как получить возможность подключить extra.h ко всем (или не всем но нескольким - по желанию) модулям проекта? smile 

--------------------
Наносите пользу и причиняйте добро!
PM MAIL   Вверх
Любитель
Дата 19.10.2006, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Вообще такое решение - не лучший вариант...
Но раз уж просят.
Исправляется так:
1. ExtraBuild.h:
Код

#ifndef EXTRA_H_
#define EXTRA_H_

#ifdef _EXTRABUILD

void _mes(LPCTSTR MyParam);

#define _extra_func(Param) _mes(Param)

#else // _EXTRABUILD

#define _extra_func(Param)

#endif // _EXTRABUILD

2. ExtraBuild.cpp
Код

#include "ExtraBuild.h"

#ifdef _EXTRABUILd

void _mes(LPCTSTR MyParam)
{ 
  // ....
}

#endif




--------------------
PM MAIL ICQ Skype   Вверх
Gwendolen
Дата 19.10.2006, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 5.4.2005

Репутация: нет
Всего: 1



Цитата(Любитель @ 19.10.2006,  10:34)
Вообще такое решение - не лучший вариант...

А как лучше, чтобы не портить читаемость кода МНОГОЧИСЛЕННЫМИ #ifdef _EXTRABUILD ... #endif?
--------------------
Наносите пользу и причиняйте добро!
PM MAIL   Вверх
maxim1000
Дата 19.10.2006, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



Цитата(Gwendolen @  19.10.2006,  10:13 Найти цитируемый пост)
А как лучше, чтобы не портить читаемость кода МНОГОЧИСЛЕННЫМИ #ifdef _EXTRABUILD ... #endif?

а что конкретно нужно?


--------------------
qqq
PM WWW   Вверх
Gwendolen
Дата 19.10.2006, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 5.4.2005

Репутация: нет
Всего: 1



Цитата(maxim1000 @  19.10.2006,  11:45 Найти цитируемый пост)
а что конкретно нужно?

Нужно не сильно испортив читабельность исходного кода, физически исключить из определенной сборки некоторые процедуры.

А так как тема называется Структура проекта С+ хотелось бы получиь информацию о модульном программировании на С++, из тех учбников что есть уменя дальше самых общих случаев ни чего нет (справочная информация по С++ на моем винте занимает 120 747 771 байт smile ). Вчера несколько часов искал в нете, но ничего существенного не нашел. 
--------------------
Наносите пользу и причиняйте добро!
PM MAIL   Вверх
Daevaorn
Дата 19.10.2006, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Gwendolen,
на multiple definition у тебя ругается потому, что функция реализована непосредственно в заголовочном файле. Сделай её inline и должно пройти.
Цитата(Gwendolen @  19.10.2006,  21:58 Найти цитируемый пост)
Нужно не сильно испортив читабельность исходного кода, физически исключить из определенной сборки некоторые процедуры.

Лучше препроцессорв не придумали. Правда можно менять варианты реализации, просто линкуя разные объектные файлы или статические библиотеки. Тогда не нужно трогать заголовки.
Цитата(Gwendolen @  19.10.2006,  21:58 Найти цитируемый пост)
о модульном программировании на С++,

В привычном понимаии (например как в Delphi) в С++ такого нет. Вся модульность это статические библиотеки и динамические библиотеки. Выбирать конкретную реализацию стоит на основе требований проекта.
PM MAIL WWW   Вверх
Gwendolen
Дата 19.10.2006, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 5.4.2005

Репутация: нет
Всего: 1



Цитата(Daevaorn @  19.10.2006,  21:05 Найти цитируемый пост)
Лучше препроцессорв не придумали

А что мой пример, не юзает препроцессор, но с помощью макросов.
А так определив функции в CPP, а объявив в H все заработало. 

--------------------
Наносите пользу и причиняйте добро!
PM MAIL   Вверх
JackYF
Дата 20.10.2006, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Вопрос по этой же теме:

В header - файле задаются следующие константы:

Код

#ifndef yf_messagesH
#define yf_messagesH

const char* Mes1 = "skljdfsdkflsd";
const char* Mes2 = "skjfsdfo[qwfj";
......
const char* MesN = "suiodfuisdfisduf";

#endif


Код не буквальный, сам факт, что задается несколько константных строк.

Если подключать этот файл к нескольким cpp-файлам, то компилер GCC ( Code::Blocks 1.0 RC2 ) выдает ту же самую ошибку:
Multiple definition < здесь каждая из объявленных строчек >

Причем ошибки выдает одновременно и в моих header -ах, и в своих библиотеках.

У кого было что-то похожее и чем можно это исправить?


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Damarus
Дата 20.10.2006, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 671
Регистрация: 6.5.2006

Репутация: 6
Всего: 29



JackYF, ответ тот же:
file.h
Код
#ifndef yf_messagesH
#define yf_messagesH

extern const char* Mes1;
extern const char* Mes2;
......
extern const char* MesN;

#endif


file.cpp:
Код
const char* Mes1 = "skljdfsdkflsd";
const char* Mes2 = "skjfsdfo[qwfj";
......
const char* MesN = "suiodfuisdfisduf";

PM MAIL ICQ Jabber   Вверх
Earnest
Дата 20.10.2006, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(Gwendolen @  19.10.2006,  22:19 Найти цитируемый пост)
А что мой пример, не юзает препроцессор, но с помощью макросов.

Это и есть использование препроцессора.

Я еще иногда, чтобы подчеркнуть отладочность кода, использую макросы типа DEBUG_ONLY:

Определение (в каком-нибудь общем h-файле):
Код

#ifdef _DEBUG
#define DEBUG_ONLY(f)      (f)
#else
#define DEBUG_ONLY(f)      ((void)0)
#endif


Использование:
Код

DEBUG_ONLY (DoSomething (with, anything));


Очевидно, что вместо DEBUG, можно использовать и другие макросимволы. Желательно только, чтобы название макроса отражало суть. Тогда в коде сразу видно, что к чему.
Закрывать ли макросимволом тело функций - дел вкуса. Я лично обычно не закрываю - это дело по ходу проекта по 10 раз меняется.



--------------------
...
PM   Вверх
JackYF
Дата 20.10.2006, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Damarus, respect. Не подумал.

P.S. Билдер-то такую штуку компилил нормально, вот я уже и привык smile


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0534 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.