Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как правильно собрать файлы проекта?


Автор: Alca 26.11.2008, 10:48
Как правильно собрать файлы проекта?

1. Модули с функциями:    
    MyStrFunc.cpp        //функции не являются методами каких-либо классов
Код

void Func1() {....}
void Func2() {....}
void Func3() {....}

MyFSOStrFunc.cpp    //функции не являются методами каких-либо классов
Код

void Func1() {....}
void Func2() {....}
void Func3() {....}
 

2. Классы:
CIni.h
Код

//объявление класса 
class CIni {/*....*/)

CIni.cpp
Код

#include "CIni.h"
#include "MyStrFunc.cpp"
#include "MyFSOStrFunc.cpp"
            
//реализация класса
//...

CPerform.h
Код

//объявление класса 
class CPerform {/*....*/)

CPerform.cpp
Код

#include "CPerform.h"
#include "MyStrFunc.cpp"    
#include "MyFSOStrFunc.cpp"    
            
//реализация класса
//...

     
3. Главный модуль:
uMain.h
uMain.cpp
Код

//Делаю "Projject -> Add Existing Item..." и подключаю к проекту классы
#include "CIni.h"
#include "CPerform.h"
    
int WINAPI WinMain(HINSTANCE hInstance,    HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) {
        //...
}


Результат:    
Код

//......    
Error    1    error LNK2005: "long __cdecl StrToLONG(char const *,long,int)" (?StrToLONG@@YAJPBDJH@Z) already defined in uMain.obj    CIni.obj
Error    2    error LNK2005: "unsigned long __cdecl StrToDWORD(char const *,unsigned long,int)" (?StrToDWORD@@YAKPBDKH@Z) already defined in uMain.obj    CIni.obj
Error    163    error LNK2005: "long __cdecl StrToLONG(char const *,long,int)" (?StrToLONG@@YAJPBDJH@Z) already defined in uMain.obj    CPerform.obj
Error    164    error LNK2005: "unsigned long __cdecl StrToDWORD(char const *,unsigned long,int)" (?StrToDWORD@@YAKPBDKH@Z) already defined in uMain.obj    CPerform.obj
//......

Ключевая фраза здесь: "already defined".  smile 

Автор: jonie 26.11.2008, 11:18
заглушки против двойных включений стоят на h файлах ?

Автор: Alca 26.11.2008, 11:21
Стоят:
Код

#pragma once

#ifndef ИмяКлассаH
#define ИмяКлассаH 


Добавлено через 13 минут и 4 секунды
Как правильно подключить класс к проекту?

Автор: 586 26.11.2008, 12:28
Цитата(Alca @  26.11.2008,  10:48 Найти цитируемый пост)
#include "MyStrFunc.cpp"
#include "MyFSOStrFunc.cpp"

Нужно указывать .h-файлы, в которых описаны прототипы функций.
MyStrFunc.h
Код
#ifndef MyStrFunc_H
#define MyStrFunc_H

void Func1();
void Func2();
void Func3();

#endif

MyFSOStrFunc.h
Код
#ifndef MyFSOStrFunc_H
#define MyFSOStrFunc_H

void Func1();
void Func2();
void Func3();

#endif

CIni.cpp
Код
#include "CIni.h"
#include "MyStrFunc.h"
#include "MyFSOStrFunc.h"

//...

CPerform.cpp
Код
#include "CPerform.h"
#include "MyStrFunc.h"
#include "MyFSOStrFunc.h"

//...

Автор: Alca 26.11.2008, 12:50
586, сделал как ты написал:
Код

Error    11    error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl sTypeToStr<double>(double)" (??$sTypeToStr@N@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@N@Z) referenced in function "public: void __thiscall CPerform::vStop(void)" (?vStop@CPerform@@QAEXXZ)    CPerform.obj

CPerform.cpp
Код

void CPerform::vStop() {
    //...
    std::string str1 = sTypeToStr(1); //компилиться
    //...
    //если sTypeToStr с целочисленной переменной, то всё компилиться, а с double не хочет:
    std::string str2 = sTypeToStr(1.0);  //не компилиться
}

CXString.cpp (выше был как MyStrFunc.cpp)
Код

#include <assert.h>        
#include <sstream>
#include <iostream>
#include <windows.h>
#include <string>
#include <vector>
#include <sstream>
#include <tchar.h>
#include <stdlib.h>
#include <iostream>
//...
template <typename T> std::string sTypeToStr(T val) {
    std::ostringstream oss;
    oss << val;

    return oss.str();
}

Добавляю след. функцию (без шаблонов) и все компилться:
Код

std::string sTypeToStr(double val) {
    std::ostringstream oss;
    oss << val;

    return oss.str();
}

Почему не работает с шаблоном? 
P.S. Эта функция sTypeToStr вызывается не один раз и с разными параметрами.


Автор: 586 26.11.2008, 13:45
Реализуй шаблонную функцию в .h-файле.
Или сделай вызов этой функции в CXString.cpp для double.
Код
template <typename T> std::string sTypeToStr(T val) {
    std::ostringstream oss;
    oss << val;
    return oss.str();
}

void test()
{
    sTypeToStr(1);
    sTypeToStr(1.0);
}


другого выхода я не вижу...

Цитата
Почему не работает с шаблоном? 

С шаблоном не работает, потому что реализации для double нету в объектном файле CXString.obj... Не будет же компилятор делать реализацию шаблонных функций для всех существующих типов. Для типа int он сделал реализацию, потому что эта функция вызывается где-то в CXString.cpp.
Когда компилируется CXString.cpp, компилятор не знает о других .cpp-файлах.

Автор: Alca 26.11.2008, 14:00
Цитата

Реализуй шаблонную функцию в .h-файле.

Типа вместо прототипа:
Код

template <typename T> std::string sTypeToStr(T val);

написать:
Код

template <typename T> std::string sTypeToStr(T val) {
    std::ostringstream oss;
    oss << val;
    return oss.str();
}

в CXString.h? да?

Автор: 586 26.11.2008, 14:04
да.

Автор: Alca 26.11.2008, 14:10
Спасибо 586, выручил.  smile 
Я тебе там крестик поставил. 
P.S. Действительно эта функция вызывалась для int. smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)