Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Не понятные проблемы в классе. WideString - одна на всех? Или может я не понял???

1
01 ноября 2005 года
kot_
7.3K / / 20.01.2000
Получается достаточно странная ситуация. Есть код.
Код:
//Собственно объявление
struct T{
 EmployeeStatus status;
 long employeesid;
 int id;
 BSTR name;
 BSTR group;
 BSTR str;
 long pointid;
 TTimer *timer;
 void __fastcall timerevent(TObject *Sender);
 TRemouteModuleImpl *ra;
 TdmMain *dm;
 T(unsigned long time = 0);
 ~T();
 unsigned long timein;
 unsigned long timeout;
 unsigned long duration;
};
T::T(unsigned long time){
 id = 0;
 name = WideString("");
 group = WideString("");
 str = WideString("");
 pointid = 0;
 timer = NULL;
 dm = NULL;
 timein = time;
 timeout = 0;
 duration = 0;
}
T::~T(){
 delete timer;
 delete dm;
 timer = NULL;
 dm = NULL;
}
typedef vector<T>E;

естественно есть форма - которая отображает данные этого класса:
 
Код:
class TfmMain : public TForm
{
....
private:   

E employeeV;
public:     // User declarations
        __fastcall TfmMain(TComponent* Owner);
        long __fastcall Login(TnRemouteModuleImpl *ea,BSTR login,long pointid,BSTR pass);

есть собственно функция - точнее две - одна рабочая вторая логирует
Код:
long __fastcall TfmMain::Login(TRemouteModuleImpl *ea,BSTR login,long pointid,BSTR pass){
dmMain = new TdmMain(NULL);//Создаем датамодуль
LogEventsE(-1,-1,login,NULL);//пишем в лог - что ктото хочет залогинится
WideString temp = "Provider=SQLOLEDB.1;Password="+WideString(pass)+";Persist Security Info=True;
User ID="+WideString(login)+";Initial Catalog=#######;Data Source="+WideString(Server)+";Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;
Use Encryption for Data=False;Tag with column collation when possible=False";//Формируем строку подключения
//Передаем имя и строку в дата модуль
 if(!dmMain->SetConnect(login,temp)){
   return -1;
 }
//Если все путем  - увеличиваем колво юзеров
  employeenumb++;
//Помещаем класс и заполняем параметры
  employeeV.push_back(T(lasttimesec));
  employeeV.back().str = temp;
  employeeV.back().status = LoginE;
  employeeV.back().ra = ea;
  employeeV.back().dm = dmMain;
   employeeV.back().name = login;
  employeeV.back().pointid = pointid;
   employeeV.back().dm->ado1->Parameters->ParamByName("@login")->Value = employeeV.back().name;
//А вот здесь фигня начинается.  employeeV.back().dm->ado1->ExecProc();
  employeeV.back().group = WideString(employeeV.back().dm->ado1->Parameters->ParamByName("@###########")->Value);
  employeeV.back().id = employeeV.back().dm->ado1->Parameters->ParamByName("@########")->Value;
  employeeV.back().dm->ado2->Parameters->ParamByName("@########")->Value = employeeV.back().id;
  employeeV.back().dm->ado2->ExecProc();

  employeeV.back().employeesid = employeeV.back().dm->ado2->Parameters->ParamByName("@sessionid")->Value;
//Функция которая выдает ошибку  LogEventsE(employeeV.back().employeesid,employeeV.back().id,employeeV.back().name,employeeV.back().status);
  employeeV.back().ra->Fire_OnLogin(login,employeeV.back().group,employeeV.back().id,employeeV.back().employeesid);
  employeeV.back().dm->ado3->Parameters->ParamByName("@id")->Value =   employeeV.back().id;
  employeeV.back().status = WaitMessageE;
  employeeV.back().dm->ado3->Active = true;
//Функция которая выдает ошибку  LogEventsE(employeeV.back().employeesid,employeeV.back().id,employeeV.back().name,employeeV.back().status);
  if(employeeV.back().dm->ado3->RecordCount)
   employeeV.back().ra->Fire_OnNewMessage(employeeV.back().id);
  return  employeeV.back().employeesid;
}
//--------Запись данных в лог и отображение на экране----------
void __fastcall TfmMain::LogEventsE(int SID,int ID, const WideString Name,EmployeeStatus Status){
 String Task;
 if(SID < 0){
   Task = IntToStr(SID)+"\t "+IntToStr(ID)+" \t"+WideCharToString(Name)+"\t Connectig..."+"\t"+DateTimeToStr(Now());
 }
 else{
 String status;
  switch(Status){
  case LoginE: status="Login";break;
  case Sending: status ="Sending";break;
  case Sent: status = "Send";break;
  case Wait: status = "Wait";break;
  case Receiving: status = "Receiving";break;
  case Received: status = "Received";break;
  case SendMessageE: status = "SendMessage";break;
  case ReceiveMessage: status = "ReceiveMessage";break;
  case WaitMessageE: status = "WaitMessage";break;
  case LoginOutE: status = "LoginOut";break;
  }
Task = IntToStr(SID)+"\t"+IntToStr(ID)+"\t"+ WideCharToString(Name)+"\t"+status+"\t"+DateTimeToStr(Now());
 }
 lbList->Items->Add(Task);
 ofstream filelog("logevents.log",ios::app);
 filelog << Task.c_str()<<"\n";
 filelog.close();
}

Все работает хорошо. Кроме одного. В логе мне отображается после подключения не имя пользователя - как должно - а почему то имя группы, причем абсолютно верное. То есть:
 
Код:
[-1  -1     Вася Пупкин    Connectig...   01.11.2005 2:23:58
01.11.2005 2:23:58  Вася Пупкин   Connect sucesfull
01.11.2005 2:23:58  Вася Пупкин   User is login
//Вот ошибка - должен быть Вася Пупкин - а почему- то выводится имя его группы.
//т.е. вместо name - group
14  1   Галимый юзер Login   01.11.2005 2:23:58
14  1   Галимый юзер WaitMessage 01.11.2005 2:23:58

Блин ничего не понимаю. Проверил все - процедура возращающая группу и ид - работает прекрасно. Но имя пользователя куда пропадает? Если возникает такой глюк - значит что то гдето я забыл?
Да все что в моем сообщении не объявлено - в реальном коде объявлено ВСЕ. Просто полный листинг не приводил - весьма велик.
246
01 ноября 2005 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by kot_
Получается достаточно странная ситуация. Есть код.
Код:
//Собственно объявление
struct T{
 ...
 BSTR name;
 BSTR group;
 BSTR str;
 ...
};
T::T(unsigned long time){
 ...
 name = WideString("");
 group = WideString("");
 str = WideString("");
 ...
}
...


Знатоки С++ АУ!? BSTR форева, а куда после конструктора девается объект WideString?

1
01 ноября 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by GIZMO
Знатоки С++ АУ!? BSTR форева, а куда после конструктора девается объект WideString?


Сделал так:

 
Код:
..
ZeroMemory(name,0);
..

ничего не изменило.
1
01 ноября 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by kot_
Сделал так:
 
Код:
..
ZeroMemory(name,0);
..

ничего не изменило.


Блин. Туплю. Вобщем если выкинуть иницыализацию из конструктора класса и использовать функции для копирования строк- получается такая картина -
вот этот код выполняется:

 
Код:
wcsncpy(employeeV.back().str,temp.c_bstr(),temp.Length());
  employeeV.back().status = LoginE;
  employeeV.back().ra = ea;
  employeeV.back().dm = dmMain;

а при попытке обращения к полю name - вылетает ошибка - банальная ошибка доступа.
Нифига не понимаю.
1
01 ноября 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by kot_
Блин. Туплю. Вобщем если выкинуть иницыализацию из конструктора класса и использовать функции для копирования строк- получается такая картина -
вот этот код выполняется:
 
Код:
wcsncpy(employeeV.back().str,temp.c_bstr(),temp.Length());
  employeeV.back().status = LoginE;
  employeeV.back().ra = ea;
  employeeV.back().dm = dmMain;

а при попытке обращения к полю name - вылетает ошибка - банальная ошибка доступа.
Нифига не понимаю.


Чем дальше в лес - тем толще партизаны. Видимо всеж надо идти спать (пить, выть, курить) :) нужное подчеркнуть. Если в классе поля сделать типа WideString - все работает. ПОЧЕМУ? В чем моя ошибка в использовании BSTR?

246
01 ноября 2005 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by kot_
Если в классе поля сделать типа WideString - все работает. ПОЧЕМУ? В чем моя ошибка в использовании BSTR?


BSTR - указатель на wchar_t (могу ошибится, но наверняка где-то глубоко в хедерах есть #define wchar_t* BSTR). Ты делаешь:

 
Код:
BSTR str = WideString("");

что вполне допускает класс WideString, но ТЫ делаешь это в конструкторе т.е. - локально, а повыходе из конструктора где объект(который хранит саму строку)? Нету! В первом случае читал мусор, а во втором AV.
1
01 ноября 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by GIZMO
BSTR - указатель на wchar_t (могу ошибится, но наверняка где-то глубоко в хедерах есть #define wchar_t* BSTR). Ты делаешь:
 
Код:
BSTR str = WideString("");

что вполне допускает класс WideString, но ТЫ делаешь это в конструкторе т.е. - локально, а повыходе из конструктора где объект(который хранит саму строку)? Нету! В первом случае читал мусор, а во втором AV.

Сенкс. Я как-то не сообразил - что любая иницализация в конструкторе указателя в конечном итоге обречена :) Что в принципе никак не помешало мне обнулить указатели на другие объекты. Инерция.

585
03 ноября 2005 года
honeybeer
297 / / 06.09.2004
Цитата:
Originally posted by kot_
Сенкс. Я как-то не сообразил - что любая иницализация в конструкторе указателя в конечном итоге обречена :) Что в принципе никак не помешало мне обнулить указатели на другие объекты. Инерция.


ИМХО для BSTR лучший метод выделения памяти - SysAllocString

Цитата:
BSTR SysAllocString(sz)
OLECHAR FAR* sz

Allocates a new string and copies the passed string into it. Returns NULL if insufficient memory exists or if NULL is passed in.

Parameter

sz

A zero-terminated string to copy.

Return Value

If successful, points to a BSTR containing the string. If insufficient memory exists or sz was NULL, returns NULL.
Strings created with SysAllocString should be freed with SysFreeString.

Example
 
Код:
inline void CStatBar::SetText(OLECHAR FAR* sz)
{

SysFreeString(m_bstrMsg);
m_bstrMsg = SysAllocString(sz);
}



Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог