Поиск:

Ответ в темуСоздание новой темы Создание опроса
> static __stdcall в классе, не видит члены-данные :P 
V
    Опции темы
NYX
  Дата 19.4.2010, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Здравствуйте! вопрос двоешника:
[BCC32 Error] script.hpp(245): E2231 Member SCRIPT::Message cannot be used without an object

Возникает когда в статической функции класса, пытаюсь вызвать элементы этого самого класса.

Код

typedef class SCRIPT{
    public:
        SCRIPT();
        ~SCRIPT();
        SCRIPT * Handle; 
        char Message[21];
    public:
    static unsigned long __stdcall script_function(void *Argument); // функция потока
    bool ThreadEnabled;

} SCRIPT;

// ----------------------------------------------------------------------------------------------------------------------------- //
unsigned long __stdcall SCRIPT::script_function(void *Argument){
    SF:
    if (ThreadEnabled){ // аналогично нижеперечисленному
        StrCpy(Message, "Не видит переменную!"); // В этом месте ошибка! Пишет что необходим ЖИВОЙ экземпляр класса \ ОБЪЕКТ :(
    }else return 0;
    goto SF;
}



Само собой код примерный, не думаю что будет вам удобно просматривать огрооооомный листинг того что там есть.... в общем набросал саму суть. На названия и прочее не обращайте внимание могут быть ошибки и не совпадения (лень проверять). Заранее благодарю за ответы и помощ   smile  smile 

Это сообщение отредактировал(а) NYX - 19.4.2010, 18:46
--------------------
'long long long' is too long for GC
PM   Вверх
ИванМ
Дата 19.4.2010, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 5
Всего: 23



Цитата(NYX @  19.4.2010,  18:27 Найти цитируемый пост)
Возникает когда в статической функции класса, пытаюсь вызвать элементы этого самого класса

В статической функции нельзя обращаться к элементам этого самого класса. Можно только через объект данного класса.

Это сообщение отредактировал(а) ИванМ - 19.4.2010, 18:42
PM MAIL   Вверх
NYX
Дата 19.4.2010, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Да это оно понятно smile Как можно обойти эту незадачу? smile  Если бы было бы возможно такое использование, компилятор бы не матюгался бы smile Как можно передать в такую функцию дескриптор объекта, что бы по нему производить вызов элементов класса \ объекта?

Это сообщение отредактировал(а) NYX - 19.4.2010, 18:45
--------------------
'long long long' is too long for GC
PM   Вверх
ИванМ
Дата 19.4.2010, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 5
Всего: 23



NYX, просто создать еще один аргумент - ссылку на объект данного класса.
PM MAIL   Вверх
NYX
Дата 19.4.2010, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



А передача аргументов в поток? При попытке отправить в DWORD инициатора потока ДЕСКРИПТОР на объект, опять же возникает ошибка, что мол невозможно привести CLASS_OBJECT к unsigned long :(
--------------------
'long long long' is too long for GC
PM   Вверх
ИванМ
Дата 19.4.2010, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 5
Всего: 23



Цитата(NYX @  19.4.2010,  18:47 Найти цитируемый пост)
А передача аргументов в поток? При попытке отправить в DWORD инициатора потока ДЕСКРИПТОР на объект, опять же возникает ошибка, что мол невозможно привести CLASS_OBJECT к unsigned long :( 

Ничего не понял. Пример, пож-та.
PM MAIL   Вверх
NYX
Дата 19.4.2010, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



WIN APIшный Createthread где в виде аргументов используется указатель на функцию потока и указатель на DWORD аргумент. Это единственное что я могу передать в функцию потока :(

Код

void __fastcall SCRIPT::Start_BRN_Generator(){
    DWORD dwThreadID, dwThrdParam = 1;
    HANDLE hThread;

    hThread=CreateThread(NULL, 0, _BRN, &dwThrdParam, 0, &dwThreadID);
    CloseHandle(hThread);
    _BRN_ENABLED = 1;
}

--------------------
'long long long' is too long for GC
PM   Вверх
ИванМ
Дата 19.4.2010, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 5
Всего: 23



NYX, к DWORD можно привести любой указатель с помощью обычной операции приведения типа.
Можно текущий объект класса (DWORD)(this).

PM MAIL   Вверх
NYX
Дата 19.4.2010, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



[BCC32 Error] script.hpp(329): E2031 Cannot cast from 'SCRIPT' to 'unsigned long'
и тут же
[BCC32 Error] script.hpp(332): E2034 Cannot convert 'unsigned long (__stdcall *)(SCRIPT *)' to 'unsigned long (__stdcall *)(void *)'

Это сообщение отредактировал(а) NYX - 19.4.2010, 19:10
--------------------
'long long long' is too long for GC
PM   Вверх
ИванМ
Дата 19.4.2010, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 5
Всего: 23



Цитата(NYX @  19.4.2010,  19:08 Найти цитируемый пост)
[BCC32 Error] script.hpp(329): E2031 Cannot cast from 'SCRIPT' to 'unsigned long'

Я говорил про указатель, а не объект.

Цитата(NYX @  19.4.2010,  19:08 Найти цитируемый пост)
[BCC32 Error] script.hpp(332): E2034 Cannot convert 'unsigned long (__stdcall *)(SCRIPT *)' to 'unsigned long (__stdcall *)(void *)'

Код покажите, что вы там передаете.
PM MAIL   Вверх
NYX
Дата 20.4.2010, 01:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Вот так работает

Код

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

#include <vcl.h>
#pragma hdrstop

#include <tchar.h>
//---------------------------------------------------------------------------
typedef class SCRIPT{
    public:
    char * Msg;
} SCRIPT;
//---------------------------------------------------------------------------
unsigned long __stdcall MyFunction(DWORD &Object){
((SCRIPT*)Object)->Msg = "Hello!";
return 0;
}
//---------------------------------------------------------------------------
void CallMyFunction(SCRIPT *Object){
DWORD * SC_Object = (DWORD*)&Object;
MyFunction(*SC_Object);
}
//---------------------------------------------------------------------------
#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
SCRIPT * _SCRIPT = new SCRIPT;
CallMyFunction(_SCRIPT);
ShowMessage(_SCRIPT->Msg);
delete _SCRIPT;
    return 0;
}
//---------------------------------------------------------------------------


Вот так не хочет работать... пишет что невозможно привести unsigned long к void  smile 

[BCC32 Error] File1.cpp(24): E2034 Cannot convert 'unsigned long (__stdcall *)(unsigned long &)' to 'unsigned long (__stdcall *)(void *)'
и
[BCC32 Error] File1.cpp(24): E2342 Type mismatch in parameter 'lpStartAddress' (wanted 'unsigned long (__stdcall *)(void *)', got 'unsigned long (__stdcall *)(unsigned long &)')

Код

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

#include <vcl.h>
#pragma hdrstop

#include <tchar.h>
//---------------------------------------------------------------------------
typedef class SCRIPT{
    public:
    char * Msg;
} SCRIPT;
//---------------------------------------------------------------------------
unsigned long __stdcall MyFunction(DWORD &Object){
((SCRIPT*)Object)->Msg = "Hello!";
return 0;
}
//---------------------------------------------------------------------------
void CallMyFunction(SCRIPT *Object){
DWORD * SC_Object = (DWORD*)&Object;
DWORD dwThreadID;
HANDLE hThread;

hThread=CreateThread(NULL, 0, MyFunction, *SC_Object, 0, &dwThreadID);
CloseHandle(hThread);
}
//---------------------------------------------------------------------------
#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
SCRIPT * _SCRIPT = new SCRIPT;
CallMyFunction(_SCRIPT);
ShowMessage(_SCRIPT->Msg);
delete _SCRIPT;
    return 0;
}
//---------------------------------------------------------------------------


P.S. - код уже раз 50 в этом месте менялся, счас делаю в отдельном проекте, что бы не листать на пол экрана.... тут в функция вне класса, но смысл думаю не меняется...
--------------------
'long long long' is too long for GC
PM   Вверх
NYX
Дата 20.4.2010, 01:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



LPVOID    
Указатель на любой тип. Этот тип объявлен в Windef.h как показано ниже:
typedef void *LPVOID;

Один фиг не вкурю :( Никогда не пользовался такими указателями :( Ну передал я указатель на объект... а далее... как его к чеему приводить что бы можно было обращаться... блин голова опухла и уже не соображаю. Хрень какая то :(

Вот так блин работает!
Код

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

#include <vcl.h>
#pragma hdrstop

#include <tchar.h>
//---------------------------------------------------------------------------
typedef class MyClass{
public:
    char Msg;
} MyClass;
//---------------------------------------------------------------------------
static unsigned long __stdcall MyFunction(LPVOID Object){
    MyClass * _MyClass = reinterpret_cast<MyClass*>(Object);
    _MyClass->Msg = '5';
    return 0;
}
//---------------------------------------------------------------------------
void __fastcall CallMyFunction(MyClass *_MyClass){
MyFunction(reinterpret_cast<LPVOID>(_MyClass));
}
//---------------------------------------------------------------------------
#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
    MyClass * _MyClass = new MyClass;
    CallMyFunction(_MyClass);
    ShowMessage(_MyClass->Msg);
    delete _MyClass;
    return 0;
}
//---------------------------------------------------------------------------


А вот так блин не работает :( Компилятор не ругается, запускат все гуд! Но результат 0!
Код

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

#include <vcl.h>
#pragma hdrstop

#include <tchar.h>
//---------------------------------------------------------------------------
typedef class MyClass{
public:
    char Msg;
} MyClass;
//---------------------------------------------------------------------------
static unsigned long __stdcall MyFunction(LPVOID Object){
    MyClass * _MyClass = reinterpret_cast<MyClass*>(Object);
    _MyClass->Msg = '5';
    return 0;
}
//---------------------------------------------------------------------------
void __fastcall CallMyFunction(MyClass *_MyClass){
DWORD dwThreadID;
LPVOID lpThrdParam = reinterpret_cast<LPVOID>(_MyClass);
HANDLE hThread;

hThread=CreateThread(NULL, 0, MyFunction, lpThrdParam, 0, &dwThreadID);
CloseHandle(hThread);
}
//---------------------------------------------------------------------------
#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
    MyClass * _MyClass = new MyClass;
    CallMyFunction(_MyClass);
    ShowMessage(_MyClass->Msg);
    delete _MyClass;
    return 0;
}
//---------------------------------------------------------------------------


Это сообщение отредактировал(а) NYX - 20.4.2010, 12:14
--------------------
'long long long' is too long for GC
PM   Вверх
xvr
Дата 20.4.2010, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Все должно работать. Поставь Sleep(1000) после CreateThread

PM MAIL   Вверх
NYX
Дата 20.4.2010, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



ставил задержки :(
В общем пришлось сделать глобальный массив указателей, куда конструктор класса пихает указатель на себя. В случае вызова функции потока, потоку передается номер экземпляра класса \ объекта, по которому из массива извлекаю указатель, который и используется в дальнейшем в функции. Хотя эт конечно для моего случая не обязательно, ибо функция потока один фиг запускается не более чем в одном экземпляре... так что необходимости в привязке к классу нет smile может даже вынесу её оттуда smile сделаю вне класса. Но блин на будущее всеж надо будет пошерудить, на предмет решений. 

Вот с передачей копии объекта или копии аргумента, проблем нет, а вот сам объект по ссылке не передается :(

чуть позже начирикаю БРЕДНИ которые стали решением )))

** ))) Тупая моя голова, я разрушаю класс прежде чем закрываю поток!!! В этом и вся беда!!!!!!! стало быть разрушается класс, методом которого является статическая функция потока, следовательно ... ... ...

Код

//------------------------------------------------------------------------------------------------------------------- //
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
#include <conio.h>
#include <iostream.h>

#pragma argsused
#pragma comment(lib, "vcl.lib")
//------------------------------------------------------------------------------------------------------------------- //
// Класс с функцией потока
typedef class MyClass {
    public:
        MyClass();
        MyClass * Handle;
        void __fastcall StartMyThread();
        void __fastcall StopMyThread();

        char * MessageFromThread;
        bool MyThreadEnabled;
        static unsigned long __stdcall Mythread(void *Object_Index);
        unsigned int ClassObjectIndex;
}MyClass;
//------------------------------------------------------------------------------------------------------------------- //
// Массив указателей
MyClass * MyClasses[50];
unsigned int ClassesSum = 0;
//------------------------------------------------------------------------------------------------------------------- //
MyClass::MyClass(){
    // Сдесь пихаем указатель на экземпляр объекта в глобальный массив
    MyClasses[ClassesSum] = this;
    ClassObjectIndex = ClassesSum;
    ClassesSum++;
}
//------------------------------------------------------------------------------------------------------------------- //
void __fastcall MyClass::StartMyThread(){
    // Сдесь создаем поток и отправляем в виде аргумента индекс на указатель
    // Назначаем MyThreadEnabled = true
    MyThreadEnabled = true;
    DWORD dwThreadID;
    HANDLE hThread;

    hThread=CreateThread(NULL, 0, Mythread, &ClassObjectIndex, 0, &dwThreadID);
    CloseHandle(hThread);
}
//------------------------------------------------------------------------------------------------------------------- //
void __fastcall MyClass::StopMyThread(){
    MyThreadEnabled = false;
}
//------------------------------------------------------------------------------------------------------------------- //
unsigned long __stdcall MyClass::Mythread(void *Object_Index){ // Функция потока
unsigned int * Num = reinterpret_cast<unsigned int*>(Object_Index);
//extern MyClass * MyClasses[50];
MyClasses[*Num]->MessageFromThread = "HELLO";
ShowMessage(MyClasses[*Num]->MessageFromThread);
MyClasses[*Num]->MyThreadEnabled = false;
    return 0;
}
//------------------------------------------------------------------------------------------------------------------- //
int _tmain(int argc, _TCHAR* argv[])
{
    MyClass * _MyClass = new MyClass();
    _MyClass->StartMyThread();
    Sleep(3000);
    ShowMessage(_MyClass->MessageFromThread);
    Sleep(10000);
    LOOP:
    if (_MyClass->MyThreadEnabled)
        goto LOOP;
    else
        delete _MyClass;

    return 0;
}
//------------------------------------------------------------------------------------------------------------------- //


В общем как то так....
Думаю больше 50 объектов просто не к чему будет smile В конструкторе можно повесить ограничение и \ или не создавать объект если он по счету > 50
Да и после удаления класса наобходимо отматать счетчик экземпляров на 1.


...
Отнюдь! стала вылетать пристраннейшая ошибка приошибка! Каким то левым боком, ругается на оконную процедуру и ссылается на classes.h честн сказать вобще черт ногу сломит что там происходит. но вышеперечисленный код работает только на консоли. В окошечном приложении данное подобие кода провацирует кучу каких то невероятных ошибок. Поведение программы такое:
Запускаю прогу, пинаю кнопочку РАБОТАЕТ! Все норм, все данные те что надо легко меняются и легко читаются... но как только стоит мне провести мышой по заголовку окна, ВСЕ нафиг слетает компилятор останавливается на цикле внутри потока O_O с чем это связано я представить себе даже не могу!!! К сведению - компилятор Embarcadero Code Gear RAD STUDIO триалка 2009

...

По последнему видать что то в компиляторе, так как на 6 BCB все работает превосходно. Тема закрыта smile

Это сообщение отредактировал(а) NYX - 20.4.2010, 18:42
--------------------
'long long long' is too long for GC
PM   Вверх
xvr
Дата 20.4.2010, 21:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



У вас написан знатный бред. Вполне может и не работать. Обычная передача this в качестве параметра процедуре thread'а всегда работала на ура. Кстати, чем вас TThread не устроил? И еще кстати - вы в курсе, что выполнение thread'ов надо синхронизировать?

Добавлено через 1 минуту и 58 секунд
Цитата(NYX @  20.4.2010,  14:02 Найти цитируемый пост)
ставил задержки :(
Не верю! (с) Станиславский.
Код с задержками в студию


PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


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

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


 




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


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

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