| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: COM/DCOM/ActiveX/ATL/CORBA > Подключение Com через длл |
| Автор: Zigrund 26.1.2011, 11:44 |
| Здравствуйте. Только зарегился и сразу прешёл к делу. На работе изчаю подключение com. Подключаю в длл. Всё замечательно работате при вызове моей тестовой простенькой исполнительной программой. Но когда мою длл вызывает основное наше приложение, где есть всякие оле сервера, то перестают вызываться функции кома. Никаких исключентй и ошибок не вылазит. Подобный случай был, так и не разобрались в чём дело. Мистика какая-то. Так подключаю. HRESULT hr = CoCreateInstance(CLSID_GeoDataUser, NULL, CLSCTX_LOCAL_SERVER, DIID_IGeoDataUser, (void**) &m_GeoDataUser ); m_GeoDataUser - интерфейс с которым работаю. Вообще вроде всё правильно. проверил на тысячу раз. И у меня же рабоатет. Не может быть ли там каких-нибудь пересечений с другими com объектами и оле серверами. Подскажите, как это вылечить? Я уже 3 день пытаюсь, и просто не понимаю в чём проблем. |
| Автор: xvr 26.1.2011, 11:58 |
| Проверяйте свой COM сервер. В первую очередь работу с параметрами - не удалили ли вы где чего лишнего. И не запутались ли где с подсчетом ссылок. Не пытались ли где работать с BSTR как с wchar_t* и наоборот. И еще много чего. Это не показатель. Ошибки в вашем COM сервере на игрушечной тестовой программе могли и не проявиться Давайте код, будем смотреть подробно |
| Автор: Zigrund 26.1.2011, 12:05 | ||||
Пожалуйста: Это H
Это CPP
Добавлено @ 12:05 Вроде всё просто. Я конечно начинающий программист. |
| Автор: Zigrund 26.1.2011, 15:11 |
| В программе, в которой не работает касяк возникат тут: bool __fastcall THandleCityGuide::DrawCityGuide(Graphics::TBitmap *bmpCityGuide,int DeltaMapXCityGuide,int DeltaMapYCityGuide) //m_GeoDataUser->SetScale(ZoomCityGuide,bmpCityGuide->Width / 2,bmpCityGuide->Height / 2); //m_GeoDataUser->SetScreenSize(bmpCityGuide->Width,bmpCityGuide->Height); m_GeoDataUser->SetScreenSize(500,500); //m_GeoDataUser->ShiftScreen(-DeltaMapXCityGuide,-DeltaMapYCityGuide); m_GeoDataUser->PathGif = WideString(PathImage); // путь удаляется и не усчтанавливается. m_GeoDataUser->set_PathGif(WideString(PathImage)); // путь удаляется и не усчтанавливается. //m_GeoDataUser->set_PathGif(L"C:\\Test1.bmp"); Application->MessageBox(AnsiString(m_GeoDataUser->PathGif).c_str(),0,0); m_GeoDataUser->Draw(); // а здесь ниччего не рисуется. Beep(1500,50); Application->MessageBox(AnsiString(m_GeoDataUser->get_PathGif()).c_str(),0,0); // тут ничего не вызывается Application->MessageBox(PathImage.c_str(),0,0); //bmpCityGuide->LoadFromFile(PathImage); bmpCityGuide->Canvas->Unlock(); StatuS = true; Beep(500,50); //Но никаких исключений нет. Но при этов когда сначала вызывалась функция: bool __fastcall THandleCityGuide::LoadMap(char *PathMap,double &N, double &W, double &S, double &E, double &zoom) всё было корректное. Проверял. Если после Draw вставить это: LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &lpMsgBuf,0,NULL); MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION ); То вернёт: "не удаётся найти указанный файл" |
| Автор: Zigrund 27.1.2011, 08:49 | ||||
В PathGif хранится путь к файлу, с которым работате ком объект. Я сначала и вызываю мою функцию InitDll, там устанавливаю переменную, потом мою bool __fastcall THandleCityGuide::LoadMap, ТАм эта переенная есть и доступ к ней нормальной. А потом по ходу выполнения исполнительной программы в которой не работает, вызывается функция рисования, и в ней йже ничего не работате. Как буд-то доступ блакируется. Да, Вы совершенно правы, там одна лишняяя, просто я пытался всеми способами ееё установить. Но ничего не помогло. А при работе с моей exe и одной любой строки достатточно, а лучше там вообще не одной, потому, что я её установил до этого в InitDll. И с моим exe не теряется доступ. У меня подобная ситуация была. Тоже юзал функции CoInitialize(NULL); CoUninitialize(); У меня всё работало. При том код был проверен, а на другом не моём exe не работало. Я склоняюсь, что что-то не так с исполнителной программой. Что там такое может быть. Повторюсь, там используется какой-то оле сервер. Мог там программер ошибиться, что мой софтинка не работает. У меня -то всё предельно просто. Ничего не обноляется, просто кто-то мне доступ закрывает. |
| Автор: xvr 27.1.2011, 12:22 |
Это понятно. Я спрашивал что именно там лежит (т.е. значение). Путь к файлу абсолютный или относительный? Если второе, то будут проблемы если кто то изменит текущую директорию в работающей программе (к примеру она меняется банальным вызовом диалога выбора имени файла) Это вряд ли. Вряд ли он виноват (если он только не в конец кривой и косой |
| Автор: Zigrund 27.1.2011, 14:12 | ||
Абсолютный конечно. Нет, там всё железно. Почему спросил про блокируется, потому, что функции com вызываться перстают. Точно знаю. Писал оле сервак опытный программер конечно. но он его писал быстро, так как надо было срочно, и пару мест методом тыка мог сделать. как мне сказали. У меня код проще некуда. Всего пара строк. Сами видете. Я его Вам весь целеком скинул. Может подскажете какие-нибудь стандартные места, чтобы я попросил посмотреть, где обычно бывают ошибки: На С# вроде всё нормально работате в студии. А на Buildere C++, вот такой вот канфуз непонятный. А надо на нём впервую очередь. |
| Автор: xvr 27.1.2011, 20:38 |
| Увы, в коде вроде никакого криминала в глаза не бросается. |
| Автор: Zigrund 28.1.2011, 09:08 | ||
Да, код совсем не сложный. Тогда, может из Вашего опыта подскажите, какие бывают типовые ошибки при использовании оле сервера, и мы их поищем в exe приложении в котором не работает. Спасибо за оказанную Вами помощь. |
| Автор: xvr 28.1.2011, 10:27 |
Самые частые это неправильное освобождение ресурсов (параметры освобождаются не там или не тогда, когда надо), и ошибки в подсчете ссылок (приводит к зависшим объектам или преждевременно удаленным объектам) Еще бывают всякие баги с multithread'ом (в основном это обычные баги, но есть и некоторые специфичные для COM) |
| Автор: Zigrund 28.1.2011, 10:30 | ||
Спасибо за совет. А посоветуйте, что-нибудь почитать, из серии "com для чайников". |
| Автор: jonie 29.1.2011, 12:36 |
| Дейл Роджерсон - Inside Com. http://forum.vingrad.ru/forum/topic-63870.html |
| Автор: Zigrund 31.1.2011, 12:41 | ||
Спасибо. |
| Автор: Zigrund 2.2.2011, 13:42 |
| Здравствуйте. Вообще если подключать мои функции через синхронайз, то вроде работает всё. Но при этом появляются тормоза. Может есть ещё какой-нибудь пдобный способ, но пошустрее??? Подскажите пожалуйста) |
| Автор: xvr 2.2.2011, 22:30 | ||
Ага. Проблемы с апартаментами COM Вам нужно отмаршалить интерфейс в тот поток, где вы его собираетесь вызывать (http://msdn.microsoft.com/en-us/library/ms693316%28v=VS.85%29.aspx и http://msdn.microsoft.com/en-us/library/ms691421%28v=VS.85%29.aspx) и потом можно вызывать. Но учтите, вызовы COM объекта пойдут из разных потоков в параллель, он может быть к этому не готов |
| Автор: Zigrund 3.2.2011, 11:53 | ||||
Спасибо. Буду пытаться разобраться. А вот ещё немного не потеме. Функция интерфейса принимает и возвращает VARIANT. Как в него и из него сделать double[][] (двумерный массив даблов). |
| Автор: xvr 3.2.2011, 15:16 | ||
Сначала проверить, что в VARIANT лежит SafeArray (это массивы в понимании AX). Потом проверить, что он 2х мерный. Потом сделать требуемый 2х мерный массив double'ов и поэлементно скопировать из SafeArray'я в массив. Если размеры массива известны заранее (и константны), то можно напрямую извлечь из SafeArray'я указатель на данные. |
| Автор: Zigrund 4.2.2011, 08:58 | ||||
Вообщем там одномерный массив. В exe проекте всё работает а в длл опять как-то касяк. Ничего не возвращается. Передаётся вроде нормально. |
| Автор: Zigrund 16.2.2011, 15:15 | ||||
| Всёмучаю свой ком объект. проблема с высвыбождением памяти:
Всё нормально работает, кроме этого кусочка (как раз, где обращени к ком объекту идёт):
При каждои запуске где-то 1MB памяти куда-то неизвестно уходит. В чём может быть проблема? |
| Автор: xvr 16.2.2011, 19:13 |
| Криминала не видно. Видимо проблема где то в другом месте |
| Автор: Zigrund 17.2.2011, 11:14 | ||
А у меня это единственное место, где я вариант использую. Может его как-то надо удалять особенным образом? |
| Автор: xvr 17.2.2011, 15:57 |
Нет. Variant должен удаляться сам (это VCL врапер над VARIANT'ом) |
| Автор: Zigrund 1.3.2011, 14:20 | ||
Я пока так и не разгодал тайну волшебного ключека. Без Variant всё нормлаьно, а с Variant память кушается. |