Lisp и внешний сервер автоматизации на Delphi
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Lisp и внешний сервер автоматизации на Delphi

Lisp и внешний сервер автоматизации на Delphi

Ответ
Поиск в этой теме
Непрочитано 04.10.2011, 16:16 #1
Lisp и внешний сервер автоматизации на Delphi
samos
 
Регистрация: 16.06.2010
Сообщений: 43

Здравствуйте!
Прошу помощи и совета в решении следующей проблемы.
Использую программу на AutoLisp. Диалоги реализую на Delphi.
Lisp – контроллер, Delphi – внутренний сервер автоматизации в виде dll.
При работе в 32-разрядной Windows проблем нет. AutoCad инсталлируется как 32-разрядное приложение. В его адресном пространстве работает внутренний COM-сервер.
При установке AutoCad на 64-разрядную машину, что сейчас уже далеко не редкость, использовать 32-разрядную dll в 64-разрядном процессе невозможно.
В связи с этим первый вопрос. Если COM-сервер на Delphi сделать внешним, то есть реализовать в виде отдельного приложения, то будут ли нормально взаимодействовать 64-битовый AutoCad и 32-битовый внешний COM-сервер, написанный на Delphi? Задаю этот вопрос потому, что всех тонкостей COM технологии не знаю.
Если работа с внешним сервером автоматизации в принципе возможна, тогда второй вопрос.
При работе с внутренним сервером использую интерфейсный метод, который открывает модальные формы, реализующие необходимые диалоги. Хотелось бы так же работать и с внешним сервером. Нужно, чтобы сервер запускался без главной формы, а только с COM-объектом. Если заремить в проекте создание главной формы, то COM-объект не создается. Проверял в пошаговом режиме на LISPе.
Буду признателен за все советы, по решению данного вопроса.
Просмотров: 5055
 
Непрочитано 04.10.2011, 17:21
#2
Sad Dog

Ищу работу
 
Регистрация: 12.06.2010
Сообщений: 35


На C++ это решается с помощью цикла в функции WinMain:
Код:
[Выделить все]
MSG msg;
while(GetMessage(&msg, 0,0,0))
{
  TranslateMessage(&msg);
  DispatchMessage(&msg);
}
Такой цикл крутится, пока в очереди сообщений не появится WM_QUIT.
Т.е. никакая главная "фома" не создается.
Что-то подобное, наверное, можно поискать и в дельфи.
А лучше переходи на C#.NET.
__________________
На свете счастья нет, но есть покой и воля.
Sad Dog вне форума  
 
Автор темы   Непрочитано 04.10.2011, 17:52
#3
samos


 
Регистрация: 16.06.2010
Сообщений: 43


Спасибо за совет! На Delphi у меня не только диалоги, но и многое другое - работа с базой данных, а также расчеты, которые лучше делать на сервере.
Так что менять язык и среду программирования возможности (да и желания) нет.
samos вне форума  
 
Непрочитано 04.10.2011, 18:54
#4
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372


Правильно ли я понимаю, что твой "внутренний сервер автоматизации в виде dll", это проект, у которого в dpr-файле записано:
Код:
[Выделить все]
....
exports
  DllGetClassObject,
  DllCanUnloadNow,
  DllRegisterServer,
  DllUnregisterServer;
....
Правильно ли я понимаю, что твой "внешний сервер автоматизации" - это exe-файл, который ещё и имеет "Automation Object"?

Вопрос "будут ли нормально взаимодействовать 64-битовый AutoCad и 32-битовый внешний COM-сервер" легко проверить - сделай тестовый. Ведь откуда-то ты взял, что 32-разрядную dll использовать нельзя. Проверял? Я вот не могу проверить - нет ни 64-разр ОС, ни 64-разр AutoCAD

Могу только предположить, что внешний сервер будет работать. Проверить не могу. Вопрос этот меня тоже интересует.

Ну, а запуск сервера без главной формы делается элементарно. В dpr надо руками убрать Application.CreateForm, а ShowForm сделать только в частях кода, вызываемых из клиента. Я так думаю.
ShaggyDoc вне форума  
 
Автор темы   Непрочитано 04.10.2011, 19:20
#5
samos


 
Регистрация: 16.06.2010
Сообщений: 43


Цитата:
Сообщение от ShaggyDoc Посмотреть сообщение
Правильно ли я понимаю, что твой "внутренний сервер автоматизации в виде dll", это проект, у которого в dpr-файле записано:
Код:
[Выделить все]
....
exports
  DllGetClassObject,
  DllCanUnloadNow,
  DllRegisterServer,
  DllUnregisterServer;
....
Правильно ли я понимаю, что твой "внешний сервер автоматизации" - это exe-файл, который ещё и имеет "Automation Object"?

Вопрос "будут ли нормально взаимодействовать 64-битовый AutoCad и 32-битовый внешний COM-сервер" легко проверить - сделай тестовый. Ведь откуда-то ты взял, что 32-разрядную dll использовать нельзя. Проверял? Я вот не могу проверить - нет ни 64-разр ОС, ни 64-разр AutoCAD

Могу только предположить, что внешний сервер будет работать. Проверить не могу. Вопрос этот меня тоже интересует.

Ну, а запуск сервера без главной формы делается элементарно. В dpr надо руками убрать Application.CreateForm, а ShowForm сделать только в частях кода, вызываемых из клиента. Я так думаю.
Тестировать я тоже не могу, нет 64-разрядного компьютера. Но 32-разрядная dll точно не работает с 64-разр. AutoCad. К сожалению не помню, какую ошибку выдает. Если на 64-разрядной системе стоит AutoCad 2007 (не позднее), то работает нормально.
В отношение Application.CreateForm - эту строчку я заремил. В LISPe функция vlax-get-or-create-object выдает nil. Если же оставить Application.CreateForm, то функция vlax-get-or-create-object выдает объект
samos вне форума  
 
Непрочитано 04.10.2011, 19:37
#6
trir


 
Регистрация: 18.12.2010
Сообщений: 5,107


Можно попробовать использовать Application.ProcessMessages
trir вне форума  
 
Автор темы   Непрочитано 04.10.2011, 19:53
#7
samos


 
Регистрация: 16.06.2010
Сообщений: 43


Цитата:
Сообщение от trir Посмотреть сообщение
Можно попробовать использовать Application.ProcessMessages
Как использовать? Вместо Application.Run?
samos вне форума  
 
Непрочитано 04.10.2011, 20:54
#8
trir


 
Регистрация: 18.12.2010
Сообщений: 5,107


Нет в теле, проинициировался и ждёшь когда будут распоряжения
trir вне форума  
 
Непрочитано 05.10.2011, 00:48
#9
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от ShaggyDoc Посмотреть сообщение
Ведь откуда-то ты взял, что 32-разрядную dll использовать нельзя. Проверял? Я вот не могу проверить - нет ни 64-разр ОС, ни 64-разр AutoCAD
Нельзя. Точнее можно, но через какие-то посредники (exe-файл), по аналогии с тем как работает VBA в AutoCAD x64, очень трудоёмко и медленно. Точную ссылку сейчас не дам, но когда-то интересовался этим вопросом. Думаю, что нет смысла.
Почитал, что появился (или вот вот появится) Delphi XE2 - позволяющий создавать как 32-разрядные, так и 64-разрядные приложения и dll: http://blogs.embarcadero.com/vsevolo...readyforlaunc/

Последний раз редактировалось Александр Ривилис, 05.10.2011 в 00:53.
Александр Ривилис вне форума  
 
Непрочитано 05.10.2011, 05:43
#10
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372


Цитата:
Нельзя. Точнее можно
Вот именно. "Нельзя, но если очень хочется, то можно" (С)

В Сети можно найти ряд способов, например здеся или тут

Особенно интересен способ описанный в MSDN

Вроде бы достаточно в реестр записать
Код:
[Выделить все]
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
   {AppID_GUID}
      DllSurrogate = path
Проверить это не могу, не на чем.

Что касается Delphi, то последыши Borland своей бездарной политикой сделали всё, чтобы угробить замечательное средство разработки. Всё появляется слишком поздно - и UTF, и 64-bit. Конечно, надо переходить на современные системы, беда в том, что они не становятся лучше. Не случайно очень многие до сих пор работают в последней надежной Delphi7.
ShaggyDoc вне форума  
 
Автор темы   Непрочитано 05.10.2011, 07:08
#11
samos


 
Регистрация: 16.06.2010
Сообщений: 43


Цитата:
Сообщение от ShaggyDoc Посмотреть сообщение
Ну, а запуск сервера без главной формы делается элементарно. В dpr надо руками убрать Application.CreateForm, а ShowForm сделать только в частях кода, вызываемых из клиента. Я так думаю
В таком варианте dpr-файла процесс завершается после Application.Run:
Application.Initialize;
//Application.CreateForm(TForm1, Form1);
Application.Run;
В диспетчере задач процесс не виден
samos вне форума  
 
Непрочитано 05.10.2011, 10:50
#12
Sad Dog

Ищу работу
 
Регистрация: 12.06.2010
Сообщений: 35


Как вариант, можно не комментировать Application.CreateForm(TForm1, Form1); При первом запуске сервера форма будет видима. А чтобы её убрать, нужно предусмотреть метод, делающий её свойство Visible = false и вызывать этот метод из клиента. Что-то типа:
Код:
[Выделить все]
STDMETHODIMPL TMyServer::SetVis(VARIANT_BOOL vis)
{
  Form1->Visible = vis;
  return S_OK;
}
(Пример примитивного exe-сервера есть в книге тов. Архангельского по С++ Builder. Оттуда и взят кусок кода.)

А то можно даже и не из клиента, а на форме сделать кнопку, типа "Хочешь, я исчезну из вида".
Но лучше, все таки, из клиента. Вызов любого метода автоматом запустит сервер. Он мелькнет лишь на мгновение, поскольку сразу же последует вызов метода SetVis и сделает его невидимым.
__________________
На свете счастья нет, но есть покой и воля.

Последний раз редактировалось Sad Dog, 05.10.2011 в 10:59.
Sad Dog вне форума  
 
Непрочитано 05.10.2011, 19:59
#13
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372


Цитата:
Но лучше, все таки, из клиента. Вызов любого метода автоматом запустит сервер
Правильно. Кроме того, ничего не мешает в проекте переписать Application.Run; Чтобы ничего не мелькало. Да и главную форму можно сделать фиктивной, сразу же невидимой. А уж реальные рабочие формы будут вызываться из методов.
ShaggyDoc вне форума  
 
Автор темы   Непрочитано 06.10.2011, 14:31
#14
samos


 
Регистрация: 16.06.2010
Сообщений: 43


Цитата:
Сообщение от Sad Dog Посмотреть сообщение
А чтобы её убрать, нужно предусмотреть метод, делающий её свойство Visible = false и вызывать этот метод из клиента
Как мне из клиента выполнить метод, делающий форму невидимой?
Да, этот метод я могу включить в интерфейсный метод COM-объекта. Но прежде, чем обратится к COM-объекту через интерфейсный метод, я должен у клиента отработать функцию (vlax-get-or-create-object ). А эта функция запускает приложение на сервере с его главной формой.
samos вне форума  
 
Непрочитано 06.10.2011, 17:40
#15
Sad Dog

Ищу работу
 
Регистрация: 12.06.2010
Сообщений: 35


Цитата:
А эта функция запускает приложение на сервере с его главной формой.
Правильно. И сразу же вслед за (vlax-get-or-create-object ) выполнить метод, делающий форму невидимой.
А еще лучше попробовать, как советует "полковник Вьетнамской народной армии" , у главной формы еще в дизайнере сделать видимость = false. Т.е. она создается, но на экран не выводится.
__________________
На свете счастья нет, но есть покой и воля.

Последний раз редактировалось Sad Dog, 06.10.2011 в 17:53.
Sad Dog вне форума  
 
Автор темы   Непрочитано 06.10.2011, 18:09
#16
samos


 
Регистрация: 16.06.2010
Сообщений: 43


Спасибо. Все работает нормально.
Правда на 32-разрядном компьютере.
Теперь самое главное - надо протестировать на 64-разрядном AutoCad-е
samos вне форума  
 
Непрочитано 06.10.2011, 18:26
#17
Sad Dog

Ищу работу
 
Регистрация: 12.06.2010
Сообщений: 35


Ну так расскажи, что сделал-то в результате всех дискуссий?
__________________
На свете счастья нет, но есть покой и воля.
Sad Dog вне форума  
 
Автор темы   Непрочитано 06.10.2011, 18:55
#18
samos


 
Регистрация: 16.06.2010
Сообщений: 43


На клиенте:
(setq objD (vlax-get-or-create-object "C.Dlg"))
(vlax-invoke-method objD "Dial" "VisNo")
На сервере:
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Form1.Visible:=false;
Application.Run;
В интерфейсном методе "Dial" входной параметр строка, которая сервером анализируется и в зависимости от содержания, запускаетя та или иная модальная диалоговая форма.
Если строка="VisNo", то выполняется
Form1.Visible:=false;
samos вне форума  
 
Непрочитано 06.10.2011, 19:33
#19
sevich


 
Регистрация: 17.08.2006
Israel
Сообщений: 19


Как правильно указал Александр Ривлис,Delphi XE2 успешно решает проблему. Достаточно перекомпилировать dll с Target Platform 64-bit Windows и все прекрасно работает без всяких ухищрения на 64 Windows и 64 Автокад (я пробовал на 2012 и 2011). Delphi XE2 не только вышла, но даже есть update 1.
__________________
Sevich
sevich вне форума  
 
Автор темы   Непрочитано 07.10.2011, 05:54
#20
samos


 
Регистрация: 16.06.2010
Сообщений: 43


Цитата:
Сообщение от samos Посмотреть сообщение
На клиенте:
(setq objD (vlax-get-or-create-object "C.Dlg"))
(vlax-invoke-method objD "Dial" "VisNo")
На сервере:
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Form1.Visible:=false;
Application.Run;
Если на клиента сделать
;(vlax-invoke-method objD "Dial" "VisNo")
или на сервере сделать:
//Form1.Visible:=false;,
то диалоги работают на фоне пустой главной формы




Цитата:
Сообщение от sevich Посмотреть сообщение
Достаточно перекомпилировать dll с Target Platform 64-bit Windows и все прекрасно работает без всяких ухищрения на 64 Windows и 64 Автокад (я пробовал на 2012 и 2011). Delphi XE2 не только вышла, но даже есть update 1.
Сколько стоит?
samos вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Lisp и внешний сервер автоматизации на Delphi



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Документация Проектировщику на Torrents DEM Разное 263 03.09.2024 12:25
{Конкурс} Lisp. Задачки для студентов gomer LISP 10 05.01.2011 16:33
загрузка DOS прог через LISP Gaa LISP 15 12.08.2005 19:19