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


Автор: dahilu 22.8.2012, 10:19
Main.h
Код

//---------------------------------------------------------------------------

#ifndef MainH
#define MainH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "MyTHRD.h"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TLabel *Label1;
        void __fastcall FormCreate(TObject *Sender);
private:    // User declarations
public:        // User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
int VarA;
void OutputVarA();
//---------------------------------------------------------------------------
#endif

Main.cpp
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Main.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
MyTHRD *MyT;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{

}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
        MyT=new MyTHRD(false);
}
void OutputVarA()
{
        Form1->Label1->Caption=IntToStr(VarA);
}
//---------------------------------------------------------------------------


MyTHRD.h
Код

//---------------------------------------------------------------------------

#ifndef MyTHRDH
#define MyTHRDH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include "Main.h"
//---------------------------------------------------------------------------
class MyTHRD : public TThread
{            
private:
protected:
        void __fastcall Execute();
        void __fastcall Output();
public:
        __fastcall MyTHRD(bool CreateSuspended);
};
extern int VarA;
//---------------------------------------------------------------------------
#endif


MyTHRD.cpp
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#pragma package(smart_init)
#include "MyTHRD.h"

__fastcall MyTHRD::MyTHRD(bool CreateSuspended)
        : TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall MyTHRD::Execute()
{
        Output();
}
//---------------------------------------------------------------------------
void __fastcall MyTHRD::Output()
{
        VarA=22;
        OutputVarA();
}


Компилируется но выводит в Label1 0
выдает предупреждение что она объявлена в двух модулях:

Public symbol '_VarA' defined in both module C:\PROGRAM FILES\BORLAND\CBUILDER6\PROJECTS\TESTTHREAD\MAIN.OBJ and C:\PROGRAM FILES\BORLAND\CBUILDER6\PROJECTS\TESTTHREAD\MYTHRD.OBJ

Как убрать ошибку и как тогда обратится к VarA и OutputVarA(); из потока?

Почему если #include "MyTHRD.h" и MyTHRD *MyT; сделать в Main.h будет выдаваться ошибка [C++ Error] Main.h(24): E2141 Declaration syntax error?

Автор: borisbn 22.8.2012, 10:30
1) В h-никах делают только объявление, а описание делают в cpp-шниках. Перенеси int VarA; в main.cpp, а в main.h сделай extern int VarA; (и в MyTHRD.h он уже не нужен.
2) К VCL-ным компонентам запрещено обращаться из доп.потоков, а ты это делаешь
Цитата(dahilu @  22.8.2012,  10:19 Найти цитируемый пост)
Form1->Label1->Caption=IntToStr(VarA);

для этого существует метод TThread::Synchronize()
3) (не в обиду) Рановато тебе заниматься потоками, если не умеешь объявлять и описывать переменные... ИМХО, ессно

Автор: dahilu 22.8.2012, 12:25
Цитата(borisbn @ 22.8.2012,  10:30)
1) В h-никах делают только объявление, а описание делают в cpp-шниках. Перенеси int VarA; в main.cpp, а в main.h сделай extern int VarA; и в MyTHRD.h он уже не нужен.


Спасибо за ответ, я попробовал, все заработало. но у меня все равно есть вопросы:
Почему я должен переносить объявление переменной VarA в Main.cpp? Разве объявления в Main.h некорректно? 
Из книги архангельского (стр 52 1 абзац) я понял что спецификацию extrern надо писать в модуле куда подключаю, в данном случае, Main.h, или это с потоками не работает?или я не правильно понял когда надо использовать extern?

Автор: borisbn 23.8.2012, 10:58
Цитата(dahilu @  22.8.2012,  12:25 Найти цитируемый пост)
Разве объявления в Main.h некорректно? 

нет. если в h-нике описать переменную, то, инклюдая этот h-ник в 2 разных cpp-шника ( в твоём случае Main.cpp и MyTHRD.cpp ), ты получаешь описание двух переменных с одним и тем же именем. Вот он и ругается.

и ещё. ты учёл

Цитата(borisbn @  22.8.2012,  10:30 Найти цитируемый пост)
К VCL-ным компонентам запрещено обращаться из доп.потоков, а ты это делаешь
для этого существует метод TThread::Synchronize()

?

Автор: dahilu 24.8.2012, 09:38
Цитата(borisbn @ 23.8.2012,  10:58)
и ещё. ты учёл

Цитата(borisbn @  22.8.2012,  10:30 Найти цитируемый пост)
К VCL-ным компонентам запрещено обращаться из доп.потоков, а ты это делаешь
для этого существует метод TThread::Synchronize()

?

Да учел. единственное есть вопрос, наверно из-за недопонимания как работает Syncronize():
Например есть вот такой поток
Код

class TCon : public TThread
{            
private:

protected:
        void __fastcall Execute();

public:
        __fastcall TCon(bool CreateSuspended);
        void __fastcall ThreadFunc();
      
};


В ThreadFunc() выполняются много действий  и в середине я обращаюсь к компоненту формы. мне достаточно написать Synchronize(ThreadFunc1) или мне надо написать отдельную функию ThreadSubFunc() в которой будет одно действие (обращение к форме) и тогда уже в ThreadFunc()  писать Synchronize(ThreadSubFunc) ?

Автор: borisbn 24.8.2012, 10:35
А чем ThreadFunc1 отличается от ThreadSubFunc ?
В любом случае тебе потребуется доп.функция для обращения к форме, которую нужно будет вызывать через Синхронайз

Автор: mes 26.8.2012, 08:30
Цитата(borisbn @  24.8.2012,  09:35 Найти цитируемый пост)
А чем ThreadFunc1 отличается от ThreadSubFunc ?

кол-вом действием..

Цитата(dahilu @  24.8.2012,  08:38 Найти цитируемый пост)
В ThreadFunc() выполняются много действий  и в середине я обращаюсь к компоненту формы.




dahilu, чем быстрее функция вызванная в Synchronize(), тем лучше..

Автор: borisbn 26.8.2012, 18:43
Аааа... наверное ТС опечатался. Единица после имени функции лишняя ?

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