2012-04-08 4 views
5

Я использую WM_COPYDATA для обеспечения связи между двумя моими процессами A и B. Нет проблем для обмена данными с базовыми типами данных.Передайте интерфейс другому процессу

Теперь у меня есть проблема, в каком-то случае я хочу передать интерфейс (IDispatch) из моего процесса A в мой процесс B. Возможно ли это?

+1

Нет прямого опыта работы с WM_COPYDATA. Но вы проверили это - http://www.codeproject.com/Articles/5307/Use-WM_COPYDATA-to-send-data-to-from-C-and-C-Windo. Также Джозеф Ньюком, кажется, предлагает, что это возможно - http://www.flounder.com/wm_copydata.htm (и он вообще прав со всеми вещами Win32) – Gangadhar

+0

@Gangadhar Это очень хорошая ссылка. Проблема возникает из-за того, что все данные должны быть сериализованы в буфер WM_COPYDATA - вы можете сделать это вручную (как предлагает автор), или полагаться на автоматическое маршалинг, например COM или mORMot. –

+1

Возможно, я полностью выключен, но как насчет [ObjectFromLresult] (http://msdn.microsoft.com/en-us/library/windows/desktop/dd373605%28v=vs.85%29.aspx) и [LresultFromObject ] (http://msdn.microsoft.com/en-us/library/windows/desktop/dd318557%28v=vs.85%29.aspx)? – kobik

ответ

12

Нельзя напрямую передать указатель интерфейса другому процессу. Как и любой другой указатель, интерфейс действителен только в адресном пространстве процесса, который запускает его во время выполнения. COM имеет свой собственный механизм для маршалирования интерфейсов и данных через границы процесса, даже в разных квартирах того же процесса. В случае интерфейсов, которые включают прокси и заглушки, которые запускаются в каждом процессе/квартире, и обмениваются данными друг с другом с использованием различных механизмов IPC, таких как каналы, RPC или TCP/IP. Посмотрите на эти статьи о том, как с помощью интерфейсов между процессами/квартиры осуществляется:

Inter-Object Communication

Understanding Custom Marshaling Part 1

Для того, чтобы сделать то, что вы просите, не прибегая к реализации пользовательского маршалинга, вам придется сделать один из процессов активным COM-сервером вне процесса, а затем другой процесс может использовать CoCreateInstance() или GetActiveObject(), чтобы получить указатель интерфейса на объект сервера, который работает в пределах его локального адресного пространства, и позволить COM обрабатывать детали маршалинга для тебя.

8

Это невозможно сделать напрямую, но вы можете использовать инфраструктуру сервиса Client-Server, которая может быть основана на интерфейсе.

Например, увидеть последнюю особенность нашего Open Source рамках mORMot: Interface based services sample code и this link.

Вы можете выполнить interface на удаленном процессе. Эта функция обрабатывает все средства связи фреймворка, то есть внутрипроцессный вызов, сообщения GDI, именованные каналы и TCP/HTTP. Внутри он будет использовать WM_COPYDATA для сообщений GDI, а затем передает параметры и результаты как JSON. Используйте this link, чтобы загрузить исходный код (используйте версию http://synopse.info/fossil 1.16+) и документацию (есть несколько страниц о том, как реализовать эти службы).

Проект с открытым исходным кодом, работающий с Delphi 6 до XE2.

Вы также можете открыть свой интерфейс с помощью клиентского сервера SOAP или DataSnap (если у вас есть соответствующая версия Delphi) или коммерческих пакетов n-уровня (например, http://www.remobjects.com/da). Это похоже на метод, реализованный в mORMot.

COM также является хорошим кандидатом, родным для Windows, но его сложнее инициализировать: вам нужно будет зарегистрировать COM на каждом ПК (с правами администратора), и вы не сможете это сделать работайте над сетью (DCOM устарел, помните). COM хорош, если вы хотите, чтобы ваш сервис делился с другими языками, например .Net, но только локально.

Смежные вопросы