Поиск:

Ответ в темуСоздание новой темы Создание опроса
> 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   Вверх
NYX
Дата 21.4.2010, 01:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Дурная голова рукам покоя не дает smile вся проблема изначально была (странно) из-за ребилда проекта smile

Код

SCRIPT * ScriptObject = (SCRIPT*)Object;


Работает замечательно!

Вот перечень проблем которые попались на пути:

Изначально, тупил с DWORD и только потом удосужился удостовериться в типе передаваемых аргументов, оказался LPVOID - всем указателям указатель.

Далее перенеся проект на консоль, долго мучился со слетами, ибо читалась какая то несуществующая область памяти - причина в преждевременном удалении класса smile черт побери

Далее ... удалось таки забабацать передачу индекса в виде аргумента (просто поток он как бы нужен в одном экземпляре, мне не нужен поток на класс).
Опять же какая то дрибедень случалась, ибо в момент завершения потока, вновь создаваемый поток иногда вызывал ошибки.

Затем чуть чуть подправив код в основной форме (снова на исходном проекте) начал запускать прогу но блин какие то слеты какая то ересь со стороны программы. Трассировщиком отлавливал слеты, отслеживал переменные но все было ГУД! (в поток передавал номер индекса из массива указателей). ПОТОМ!! Как выяснилось, что Code Gear как то странно работает с проектом, а точнее, ребилду при старте подлежать лишь ОСНОВНЫЕ модули проекта (типо Unit.cpp и Unit.h), и как повидимому, для какого то ускорения старта и компиляции, подключаемые (иклуденные) файлики, он почему то не ребилдит, только если явно не запросил этого. Вот такое приключение, счас все замечательно работает, приношу величайшие извинения за хламоту и мусороразведение!!! Вообще по началу тему создал от злости на происходящее и расщитывал на свои способности smile благо умудрился понять, что не так в проге smile Всем огромное спасибо smile
--------------------
'long long long' is too long for GC
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

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

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

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

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


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

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


 




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


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

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