Передача данных TClientDataset через стандартные потоки
От Dmytry Ginzburg (2:461/48.125) к All
В ответ на Заголовок предыдущего сообщения в треде (Имя Автора)
Здравствуйте, о моногоуважаемый(ая), All!
Вот.. Hабил письмецо.. А вот, что из этого вышло:
Доброго всем времени суток. Возникла следующая проблема. В связи с тем, что один COM объект не подружился с ADO (при вызове запросов, возвращающий RecordSet вываливается в AV в ntdll.dll и других библиотеках, связанных с COM, после инициализации вышеупомянутого объекта) принято решения разнести обращения к БД и работу с COM объектом по разным адресным пространствам. По причинам, упомянутым выше, COM для обмена использовать не хочу. Поэтому решил использовать пайпы для обмена между приложениями. Я написал следующее консольное приложение для работы с БД.
_!--==> А тута Windows Clipboard начинается... <==--!_
int main(int argc, char* argv[])
{AnsiString s="Begin of main";
OutputDebugString(s.c_str());
char c[65535];
char c2;
int t=1;
if(IsDebuggerPresent())s="I'm under debugger";else s="I am not under debugger";
OutputDebugString(s.c_str());
try{try{CoInitialize(0);
s="I've executed CoInititalize";
OutputDebugString(s.c_str());
DataModule2=new TDataModule2(0);
s="I've created DataModule2";
OutputDebugString(s.c_str());
if(!gets(c))s="I haven't got any string because of error";else{
s=c;
s="I've got connection string. It's "+s;}
OutputDebugString(s.c_str());
DataModule2->ADOQuery1->ConnectionString=c;
s="I've put connection string to ADOQuery";
OutputDebugString(s.c_str());
if(!gets(c)){s=errno;s="I haven't got any string because of error"+s;}else{
s=c;
s="I've got query for database. It's "+s;}
OutputDebugString(s.c_str());
DataModule2->ADOQuery1->SQL->Add(c);
s="I've put my query to ADOQuery";
OutputDebugString(s.c_str());
DataModule2->ADOQuery1->Open();
DataModule2->ClientDataSet1->Open();
s="I've executed query";
OutputDebugString(s.c_str());
t=DataModule2->ClientDataSet1->DataSize;
s=t;
s="DataSize is "+s;
OutputDebugString(s.c_str());
s="I've put DataSize to cout";
OutputDebugString(s.c_str());
DataModule2->ClientDataSet1->SaveToStream(str,dfXML);
t=str->Size;
char *p=(char *)&t;
//for(int i=0;i<4;cout<<*p,p++,i++);
s=str->Size;
s="I've saved query result to stream It has size "+s;
//gets(&c2);
OutputDebugString(s.c_str());
char *c1=(char *)str->Memory;
s="I've got the stream's address";
OutputDebugString(s.c_str());
//cout<<str->Size<<'\n';
for(int i=0;i<str->Size;cout<<*c1,c1++,i++);
s="I've sent stream to cout";
OutputDebugString(s.c_str());
}
__finally{
if(DataModule2)DataModule2->Free();
if(str)str->Free();
CoUninitialize();
}}
catch(Exception *e){OutputDebugString(e->Message.c_str());
cout<<e->Message.c_str();}
return 0;
}
_!--==> А тута Windows Clipboard заканчивается... <==--!_
Я переназначил стандартные потоки ввода/вывода на мои пайпы и всё хорошо работает. Hо есть одна проблема. Когда я считываю из пайпа отстриммированный dataset, то при попытке его подгрузить в dataSet в программе возникает ошибка Data Mismatch. Я прошёлся отладчиком и понял, что похоже через стандартный поток ввода/вывода некорректно передаётся символ завершения датасета. В связи с этим у меня возникает вопрос, как правильно передать символ завершения датасета из одной программы в другую через стандартный поток или добавить его уже в другой программе. Кстати, размер датасета в программе и датасета в стриме одинаковый, это я отследил. Как сделать так, чтобы правильно передался датасет из одной программы в другую?
Желаю Вам всего наилучшего, All.Дмитрий.
--- Вот такой вот наглый Дед со стажем в 3.0.1-asa9 SR1 лет!
* Origin: Default ORIGIN (FidoNet 2:461/48.125)
Ответы на это письмо:
From: Username
Заголовок следующего сообщения в треде может быть длинным и его придется перенести на новую строку
From: Username
Или коротким