| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Общие вопросы по .NET и C# > Реализация RPC |
| Автор: gpepsi 31.8.2012, 18:40 | ||
| На машине существуют COM объекты, которые реализуют некоторые интерфейсы. С другой машины необходимо удаленно вызывать методы интерфейса. Задача 1: уйти от COM объектов создав некую абстракцию. Задача 2: сделать это максимально платформонезависимо. В голову пришел простой способ реализации на основе JSON. Передача данных по сети Tcp-клиентом (может быть механизм более высокого уровня). Сначала попытался реализовать каждый метод. Например:
Соответственно, получив JSON запрос я просто проверяю метод и вызываю нужный. В рельтате получается офигенный if/else if т.к. методов много. Также возникает проблема с передвчей аргументов. Каждый метод должен знать какие аргументы каких типов должны быть переданы. Хотелось бы это унифицировать. Например, по типу класса найти нужный объект и вызвать метод по строковому имени. Только типы класса и методы передаются как строки. Можно ли это реализовать ? |
| Автор: Cheloveck 1.9.2012, 02:24 |
| Может не нужно изобретать велосипед и воспользоваться http://msdn.microsoft.com/en-us/library/dd456779.aspx? |
| Автор: gpepsi 1.9.2012, 08:15 |
я же говорил - платформонезависимо. P.S. тут искал и нашел всякие Type и GetMethod. Может как это прикрутить можно ? |
| Автор: Cheloveck 1.9.2012, 15:11 | ||
Можно использовать http://msdn.microsoft.com/en-us/library/cc668792.aspx и экспозить http://www.odata.org/, клиенты для которой есть http://www.odata.org/libraries. |
| Автор: gpepsi 2.9.2012, 08:21 | ||||
до этом машины пофигу. Вопрос к машине управления (хоть наладонник, хоть PC,...) Я создаю экземпляры COM. Получается, что мне нужно после создания держать карту Map<String, Object>, чтоб можно было найти по имени типа нужный COM ?
это понятно вот тут тоже проблема. Число и тип аргументов различны. Как выэывать методы через Invoke ? Ведь сигнатуру метода знает только вызывающий код (на управляющей машине). А код на стороне COM хотелось бы вызывать универсально. Может ли Invoke принимать массив аргументов типа object и сам понимать сколько ему аргументов нужно и какого типа ? |
| Автор: diadiavova 2.9.2012, 08:36 | ||||
Давай начнем с того, как ты их создаешь и как вообще работаешь с ком. Обычно для этого генерируется сборка взаимодействия, в которой все типы являются CLR-типами и никакой проблемы рефлексии в этом плане быть не должно. Если ты делаешь это иначе, то опиши как и почему. Поначалу ты вообще написал, что создал собственные оболочки для ком-типов(насколько я понял).
Инвоук не может, но методинфо(объект, у которого ты вызываешь инвоук) содержит сведения о параметрах. |
| Автор: gpepsi 2.9.2012, 09:13 | ||||
я создаю их через Microsoft.VisualBasic.Interaction.CreateObject получаю интерфейс, и работаю с ним вызывая методы.
то есть ему можно передать массив аргументов ? |
| Автор: diadiavova 2.9.2012, 09:19 | ||
Ну вот в этом причина того, что ты не можешь получить сведений о типе. Добавь ссылку на соответствующую библиотеку и все значительно упростится. Ну, а что по-твоему представляет из себя второй параметр метода? http://msdn.microsoft.com/ru-ru/library/a89hcwhh%28VS.100%29.aspx |
| Автор: gpepsi 2.9.2012, 10:44 | ||
а что мне это даст ? |
| Автор: diadiavova 2.9.2012, 11:09 | ||
Как минимум сведения о типах. И вот это
тебе уже не понадобится. |
| Автор: gpepsi 2.9.2012, 12:43 |
diadiavova, я слабоват в C#. Можно подробнее пояснить или примерчик для наглядности |
| Автор: diadiavova 2.9.2012, 14:56 |
Добавляешь в проект ссылку на библиотеку, в которой определены нужные ком-классы и все интерфейсы будут доступны как обычные нет типы. Дальше сможешь с помощью рефлексии получить тип по имени в том числе. Добавь ссылку и сам все увидишь. |
| Автор: gpepsi 2.9.2012, 15:28 | ||
имеется ввиду создать экземпляр по имени ? |
| Автор: diadiavova 2.9.2012, 17:04 | ||||||
Аааааааа. Не знаю с какими ком-типами ты работаешь. Для примера возьмем библиотеку Scripting Runtime. (находится по адресу C:\Windows\System32\scrrun.dll). Допустим мне пришло имя FileSystemObject и надо создать экземпляр этого типа. Для начала нам понадобится ссылка на сборку, в которой определены типы. Если ты пишешь под 4-ый фреймворк, то по умолчанию типы внедряются в твою сборку, а это нам не надо. Для того, чтобы сборка взаимодействия создавалась отдельно, в обозревателе решений открой ветку "Ссылки", найди там свою ком-библиотеку(в моем случае она называется Scripting), выдели ее и перейди в окно свойств(или через контекстное меню), там увидишь свойства сборки, тебе надо свойству "Внедрить типы взаимодействия" присвоить False. В коде сначала надо получить ссылку на сборку взаимодействия, в которой определены нужные типы. Проще всего это сделать, используя какой-нибудь тип, определенный в этой сборке. Я использовал все тот же FileSystemObject, хотя можно было и любой другой, они все имеют ссылку на свою сборку
Добавлено через 35 секунд Не забудь импортировать
|
| Автор: gpepsi 2.9.2012, 18:15 | ||
| diadiavova, спасибо. буду разбираться. З.Ы. Только еще вопрос - если экземпляр создан, то вызов
создаст еще один экземпляр или получу указатель на созданный ранее ? Мне нужно второе. |
| Автор: diadiavova 2.9.2012, 19:05 | ||||
Еще один экземпляр. Если тебе нужна переменная, ссылающаяся на тот же объект - просто присвой ей эту ссылку
|
| Автор: gpepsi 3.9.2012, 12:08 | ||||||
| что-то не получается создать объект. Добавил ссылку на объект. Смотрю Interop.MyWHostLib - WHostObj - интерфейс - WHostObjClass - класс - IWHostObj - интерфейс Получаю сборку
успешно. Создаю объект
ошибка - не можетпривести тип объекта "System.__ComObject" к типу "MyWHostLib.WHostObjClass"; Добавлено через 6 минут и 14 секунд P.S. Забыл скачать, что объект создавался так
то естьб он принимал агрументом адрес и кастовался к интерфейсу |
| Автор: diadiavova 3.9.2012, 20:57 | ||
В том коде, что ты привел, приведения типов нет, так что ошибка как раз видимо возникает там, где ты используешь CreateObject. Для чего ты его используешь - непонятно. Креэйтобжект делает то же, что и активатор, только по программному идентификатору, а не по имени класса, да и без сборки взаимодействия. Так что уж надо использовать либо то, либо другое. Для чего ты пытаешься приведение типов выполнить - тоже непонятно, тип тебе заранее известен не будет, именно поэтому приходится работать через рефлексию, так что работай с типом объект. |