dll + TSocketConnection = Abnormal Program Termination
От: sergey82  
Дата: 11.03.05 10:14
Оценка:

В нижеследующем коде я работаю с SocketConnection, но у меня есть подозрения, что я
чего-то не доделываю.


Проблема следующая:
сделел dll, которая в процессе работы, обращается к БД.
При одиночном вызове всё нормально. При повторном вызове (загрузке dll),
всё работает нормально, но после отработки dll, программа(вызывающая dll)
выпадывает с сообщением "Abnormal program termination" и закрывается.

Подозрения именно на работу с SocketConnection (или TempInterface),
поскольку, если работать не через SQL-сервер, а через файл-сервер (проделывая
абсолютно аналогичные операции) -- всё проходит нормально (ничего ни
где не закрывается...).

Кстати, плюс к этому в конце работы функции выскакивает breake point в ntdll.dll,
но к счастью, этого не видно при работе вне отладки. (что сдранно — при обращении на
файл-сервер, этот break point не приперается....)

В чём тут дело :


void TDataBaseModule::ExtractDSE(const string &Begin_DSE, const int &Level, const bool &ExtractAll)
{
TSocketConnection *SocketConnection1 = NULL;
SocketConnection1 = new TSocketConnection(NULL);

TClientDataSet *ClientDataSet1 = NULL;
ClientDataSet1 = new TClientDataSet(NULL);

if(SocketConnection1 && ClientDataSet1)
{
Label1_p0060062: // но проще непридумал (см.ниже)


// здесь инициализация, которая пригодится в LoadData
int Bounds[2] = {0,2};
Variant A = VarArrayCreate(Bounds,1, varVariant);

A.PutElement(AnsiString(Begin_DSE.c_str()), 0);
A.PutElement(static_cast<TDate>(Date()), 1);
A.PutElement(Level, 2);

WideString part("NetGraph");
WideString batch("P0060062");



if(SocketConnection1->Connected) SocketConnection1->Connected = false;
SetSocketConnection(*SocketConnection1);
SocketConnection1->Connected = true;

try {

if(SocketConnection1 && SocketConnection1->Connected)
{
IDispatch *disp = NULL;
disp = static_cast<IDispatch*>(SocketConnection1->AppServer);
IServerDataDisp TempInterface((IServerData*)disp);

// закачка данных из сервера приложений
ClientDataSet1->Data = TempInterface.LoadData(BSTR(part), A, BSTR(batch), 1);



// убываем ссылку на интерфейс
// Может чего-то не хватает здесь?!!
// (Например с TempInterface?)
disp = NULL;
SocketConnection1->Connected = false;
delete SocketConnection1;
SocketConnection1 = NULL;
}

}
catch(const Exception &e) {
if(Application->MessageBox( (e.Message+"\nПопробовать подключиться ещё раз?").c_str() ,
"Ошибка при обращении к БД для разузловки",
MB_OKCANCEL) == MB_OK)
goto Label1_p0060062;
else
throw;
}


catch(const EOleException &m) {
if(Application->MessageBox( (m.Message+"\nПопробовать подключиться ещё раз?").c_str() ,
"Ошибка при обращении к БД для разузловки",
MB_OKCANCEL) == MB_OK)
goto Label1_p0060062;
else
throw;
}

catch(...) {
if(Application->MessageBox( (string("Неопределённая ошибка")+"\nПопробовать подключиться ещё раз?").c_str() ,
"Ошибка при обращении к БД для разузловки",
MB_OKCANCEL) == MB_OK)
goto Label1_p0060062;
else
throw;

}


A.Clear();





unsigned short ci = 0, cp = 0;
unsigned short amount_par = 0, amount_all = 0;


//далее я каким-то образом укладываю полученные данные в свои внутренние структуры...
ClientDataSet1->First();
while(!ClientDataSet1->Eof)
{
const AnsiString dse1(Trim( ClientDataSet1->FieldByName("dse1")->AsString));
const AnsiString se(Trim( ClientDataSet1->FieldByName("se")->AsString));
const AnsiString cipher(Trim(ClientDataSet1->FieldByName("zak")->AsString));
const AnsiString pkp( ClientDataSet1->FieldByName("pkp")->AsString);

const string dse1_(dse1.c_str());
const string se_(se.c_str());
const string cipher_(cipher.c_str());

// находим первый ненулевой цех
int ci = ClientDataSet1->FieldByName("ci3")->AsInteger;
ci = (ci) ? (ci) : (ClientDataSet1->FieldByName("ci2")->AsInteger);
ci = (ci) ? (ci) : (ClientDataSet1->FieldByName("ci1")->AsInteger);
const int cp = ClientDataSet1->FieldByName("cp")->AsInteger;

const int amount_par = ClientDataSet1->FieldByName("kol")->AsInteger;
const int amount_all = ClientDataSet1->FieldByName("kol1")->AsInteger;

const string tmp_str(se_ + "##" + dse1_);
MyDSE->push_amount_par(tmp_str, amount_par);
MyDSE->push_amount_all(dse1_, (MyDSE->amount_all(dse1_) + amount_all));


MyDSE->push_cp(dse1_, cp);
MyDSE->push_ci(dse1_, ci);

// ставим в соответствие данному децимальному номеру шифр заказа
if(pkp != "4") // pkp != "4" -- не имеет шифр заказа
{
MyDSE->push_have_cz(dse1_, false);
} else
{
if(cipher_ != "")
MyDSE->push_cipher(dse1_, cipher_);
MyDSE->push_have_cz(dse1_, true);
}


if(se != dse1 )
MyDSE->DSE1->insert(make_pair(se_, dse1_));

ClientDataSet1->Next();

}





try {
ClientDataSet1->Close();
}
catch(...) {
Application->MessageBox("Зафиксирована какая-то ошибка при закрытии DataSet, ошибка не критична.",
"ExtractDSE()",
MB_OK);
}




delete ClientDataSet1;
ClientDataSet1 = NULL;
}

}


Я уже весь извёлся.....
Help me!

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.