В нижеследующем коде я работаю с 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!