Реализация DCOM с помощью Borland C++ 6
Вступление:
Некоторое время назад я создал по книжке руками dll, без фабрики классов и прочих наворотов, которая экспортирует CreateInstance(), возвращающую указатель на IUnknown. Т.е. всё максимально просто. Тело компонента и интерфейсы - всё создал, как положено, но руками.
Все интерфейсы наследуют IUnknown. Все они используют BSTR, SAFEARRAY и вариантные типы данных, так как это должно понадобиться для диспетчеризации.
Задача:
Теперь у меня стоит задача сделать из этого .exe, регистрируемый в реестре, умеющий экспортировать функции по сети, реализующий дуальный интерфейс (с диспетчеризацией).
Решение:
Очевидно, что создавать это правильно пользуясь уже существующими инстурментами Borland C++ 6, позволяющими большую часть получить автоматически.
При этом я совершенно не умею обращаться с Борландовскими инструментами для создания DCOM, и не нашел нормальной статьи, где для дураков объяснено, что где и зачем.
Вопрос:
МОжете ли вы мне помочь какими-то ссылками о том, как именно Borland-инструментами создать такой сервер?
В закладке ActiveX я нашел COM Object, но он почему-то создается только в дополнение к имеющемуся проекту, я не могу выбрать это, если у меня уже не открыт какой-то проект.
И при этом он у меня жалуется на то, что не реализован IDispatch, я должен его руками реализовывать, или всё-таки где-то есть галочка, отметив которую я получу реализацию автоматически?
В общем, если можете помочь ссылкой, помогите пожалуйста, если можете помочь советом, тоже :)
Заранее спасибо!
У меня возник такой вопрос. К сожалению, мне в руки попало старое издание, для Билдера5, а у меня 6ой, и, видимо, собака тут зарыта.
Для создания DCOM там рекомендуется последовательность действий
1) File->New->Application
2) File ->New->Automation Object
При этом первое создает форму. Которая меня потом преследует, потому что Visible = false её не выключает, а если я руками отключаю её создание
(например, убирая Application->CreateForm(__classid(TForm1), &Form1); ) то при использовании клиентом этого сервера вылезают ошибки (хотя работа сервера с этой формой никак не связана).
Побился и понял, что я не понимаю чего-то концептуального, что мешает мне отключить эту форму.
Как это сделать? :)
То ваш вариант создает сервер с формой для COM объектов
Вариант без формы: сначала нужно создать библиотеку СOM объектов, а не Application и потом добавить в нее новый Automation Object.
Побился и понял, что я не понимаю чего-то концептуального, что мешает мне отключить эту форму.
Как это сделать? :)
не вникая в концепцию, так:
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->ShowMainForm = false;
...
GIZMO, спасибо, это работает. Теперь надо выяснить, как правильно делается exe-шник без формы (не скрывая форму, а вообще без неё) =)
-------------
Upd: Только теперь при вставлении объекта в клиенте через Import Type Library иногда генерируется почему-то "UpServer_OCX.h", а не "UpServer_TLB.h", как описано в книге, а иногда "UpServer_TLB.h" =)
Форма убирается так Project|Remove from Project...
Только зачем? При этом твоя программа завершится сразу же после старта...
Не совсем понимаю, почему обязательно должен быть exe?
Абвиатура DCOM означает удаленный вызов объекта СOM. На стороне вызова может быть и библиотека и exe по желанию.
Или я тоже что-то концептуально не допонимаю? :)
Только зачем? При этом твоя программа завершится сразу же после старта...
ну а так получается, что если я запускаю программу вручную, то она никак сама не завершается (срока жизни формы нет).
А в идеале, если я запускаю вручную (хочу зарегистрировать в системе), то должно вылезать окошко, что мол "удачно зарегистрированы". А если я подключаюсь как к библиотеке, то срок жизни должен определяться указателями на объекты и никакого окна быть не должно.
Сейчас же или у меня есть окно, которое висит пока идёт работа с объектами в клиенте, или у меня нет окна, и тогда при запуске вручную (для регистрации) процесс запускается навечно =)
Как решают этот вопрос профессионально? :)
Не совсем понимаю, почему обязательно должен быть exe?
Абвиатура DCOM означает удаленный вызов объекта СOM. На стороне вызова может быть и библиотека и exe по желанию.
Или я тоже что-то концептуально не допонимаю? :)
Exe - свой процесс, а DLL будет крутиться в процессе клиента. Не представляю как DLL, лежащая где-то на другой машине может полностью встроиться в процесс клиента на этой машине...
+ как утверждал Дейл Роджерсон, для межпроцессового и межсетевого взаимодействия диспетчеризация не сильно замедляет работу (сопоставимо с сетевыми задержками) с сервером, а если использовать её в DLL, то порядок замедления, по сравнению с работой с обычными интерфейсами будет где-то в 100 раз. Т.е. существенно =)
Насколько это вообще критично? Потому что, вроде бы, всё равно собирается, хоть и с этими warnings =(
2) Один из методов моего интерфейса (единственный, который возвращает SAFEARRAY), UPSetTaskInfo почему-то превратился в отдельную TLB...
т.е. появились такие строчки:
extern "C" const __declspec(selectany) GUID IID_IUpiter = {0x00E87B1D, 0x710C, 0x4C69,{ 0x8A, 0xB3, 0xF0,0x22, 0x93, 0x38,0xB5, 0x55} };
extern "C" const __declspec(selectany) GUID IID_IUPObjectInside = {0xC316FFDA, 0x29B3, 0x4C5F,{ 0xAD, 0x95, 0xA8,0xE9, 0x71, 0xEC,0x49, 0x24} };
extern "C" const __declspec(selectany) GUID CLSID_Upiter = {0x519556E1, 0x5429, 0x4A17,{ 0xB4, 0xBE, 0x5F,0x2B, 0x63, 0x61,0x40, 0xD2} };
Хотя у меня всего два интерфейса (IUpiter и IUPObjectInside)... почему такое случилось? В книге тож об этом ничего нет =(