#0
by oleg_km
Написал на C# два COM-объекта, оба в одной dll в одном проекте. Хочу в метод одного передавать ссылку на объект второго, чтобы метод первого дернул метод второго. Пробовал разные варианты: 1) В параметрах нужного метода первого объекта просто указал интерфейс второго: при вызове выскочило Неизвестная ошибка 2) В параметрах нужного метода первого объекта указал object, в теле метода попытался следать приведение и через и через as, ругается: Нет такого интерфейса 3) В параметрах нужного метода первого объекта указал dynamic, все заработало, но мне так не нравится: нет типизации, нужен .Net 4, нужно на компьютер пользователя устанавливать доп. сборку Примерный код: namespace TestCOM { [Guid("E5B23F96-411D-4A67-AFBA-B3DF6B3B0ACB")] public interface ITestCOM { [DispId] void TestOCX(ITestActiveX oTest); // 1-й вариант void TestOCX(object oTest); // 2-й вариант void TestOCX(dynamic oTest); // 3-й вариант } [ProgId("TestCOM.Test"), ClassInterface(ClassInterfaceType.None), Guid("1BD846DC-63F2-4070-AF23-8AECD6C158CC")] public class CTestCOM : ITestCOM { public void TestOCX(ITestActiveX oTest) // 1-й { oTest.ShowEvent("Test parameter"); } public void TestOCX(object oTest) // 2-й { ITestActiveX ot = (ITestActiveX) oTest; ot.ShowEvent("Test parameter"); } public void TestOCX(dynamic oTest) // 3-й { oTest.ShowEvent("Test parameter"); } } [Guid("D783DC48-8FB0-4fe9-BDC2-0CEE3F5E8921")] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface ITestActiveX { [DispId] void ShowEvent(string msg); } [Guid("A94CEA0F-1CD3-4829-A75E-B8A81A1EE56D")] [ProgId("TestCOM.TestActiveX")] [ComDefaultInterface(typeof(ITestActiveX))] [ClassInterface(ClassInterfaceType.None)] public class TestActiveX : UserControl, ITestActiveX { public void ShowEvent(string msg) { MessageBox.Show(msg); } } } Очень хочу первый вариант, если что готов и на второй
#2
by Serginio1
[ClassInterface(ClassInterfaceType.AutoDual), ComVisible(true), Guid("A94CEA0F-1CD3-4829-A75E-B8A81A1EE56D"), ProgId("TestCOM.TestActiveX")]
#4
by oleg_km
TestOCX в интерфейсе ITestCOM, ну в 1С примерно так: об1 = Новый COMОбъект("TestCOM.Test"); об2 = Новый COMОбъект("TestCOM.TestActiveX"); об1.TestOCX(об2); Имеется ввиду AutoDual вместо None? Только что попробовал, тоже самое.
#5
by oleg_km
Так это вроде соответствует второму варианту. вызов метода идет, но не проходит приведение типа. Ругается что интерфейс D783DC48-8FB0-4fe9-BDC2-0CEE3F5E8921 (ITestActiveX) не отдается QueryInterface
#6
by Serginio1
У тебя не получится второй вызвать. Можно в interface ITestCOM Создать метод который создает экземпляр класса TestActiveX.
#9
by oleg_km
Подожди, в 3-м варианте через dynamic получается же. Код из в третьем варианте нормально работает, просто мне само использование dynamic не нравится.
#10
by Serginio1
Замени void TestOCX(ITestActiveX oTest); На void TestOCX(IDispoatch oTest); это будет вариант с оbject и dynamic. Просто получается разные соклассы.
#11
by oleg_km
Вот так: void TestOCX([MarshalAs(UnmanagedType.IUnknown)] object oTest); Пробовал, тоже не получилось
#15
by oleg_km
Дело в том что объекты создаются независимо. но я сейчас попробовал наоборот во второй объект передать первый и все прошло нормально. Надо аккуратно все пересобрать
#18
by oleg_km
Первый это основной coClass Как ты это понял, вообще-то это просто два разных КОМа, просто в одном проекте. Если быть точным один просто ком, второй активикс: CTestCOM : ITestCOM - просто ком TestActiveX : UserControl, ITestActiveX - активикс, я просто выкинул всякие события прочее А как тогда его дергает 1С? 1С напрямую научилось подключаться к .NET?
#20
by Serginio1
Есть такая функция dllgetclassobject которая находит нужный DLL И обычно вторым параметром передаетя IDispatch. Но проблема скорее всего в [ComVisible(true), ClassInterface(ClassInterfaceType.AutoDispatch)] public class ContainerControl : ScrollableControl, IContainerControl ComVisible(true), Designer("System.Windows.Forms.Design.ControlDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), DefaultEvent("Load"), DesignerCategory("UserControl"), ClassInterface(ClassInterfaceType.AutoDispatch), Designer("System.Windows.Forms.Design.UserControlDocumentDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(IRootDesigner))] public class UserControl : ContainerControl То есть UserControl сам реализует IDispatch. Возможно в этом проблема
#22
by Serginio1
Посмотри Но там [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] Да и для [ProgId("TestCOM.Test"), ClassInterface(ClassInterfaceType.None), Guid("1BD846DC-63F2-4070-AF23-8AECD6C158CC")] public class CTestCOM : ITestCOM [InterfaceType(ComInterfaceType.InterfaceIsDual)]
#23
by oleg_km
Решил проблему. Дело в том что когда я написал пример вызывающего кода: об1 = Новый COMОбъект("TestCOM.Test"); об2 = Новый COMОбъект("TestCOM.TestActiveX"); об1.TestOCX(об2); я немножко слукавил - только один объект создается конструкцией CreateObject, второй то сажается на форму как ActiveX. Среда 1С дает мне доступ к этому объекту как ссылку на элемент формы и судя по всему это какой-то контейнер. Т.е. когда я вызываю методы своего объекта, на самом деле я дергаю контейнер, а контейнер уже дергает мой объект, а когда я передаю ссылку в другой объект, он пытается привести тип в соответствие с указанным типом моего параметра и обнаруживает, что тип (тип контейнера) у него отсутствует. Я просто в ActiveX добавил метод, который возвращает указатель на себя, приведенный к типу своего интерфейса: public ITestOCX1 GetThis { return (ITestOCX1)this; } И вызов теперь выглядит: обТест = Новый COMОбъект("TestCOM.TestCOM1"); обТест.CallTest(ЭлементыФормы.TestOCX1.GetThis); Если это коряво, то как делать правильно?
#24
by Serginio1
Это нормально, об этом я тебе и писал в 22 (просто идет расширение GetsIDOfNames и Invoke ), но мало чем отличается от того, что я предлагал тебе в 13.
#25
by oleg_km
Я теперь понял в чем заключался совет: ссылку для дальнейшей работы в .NET нужно получать не от 1С, а от .NET
#26
by Serginio1
Я тебе в 20 писал как получает 1С IDispatch через dllgetclassobject . TestActiveX по сути реализует два IDispatch,но расширяет он методы UserControl котрый ничего не знает об ITestCOM. Но в Net могли бы и переопределить QueryInterface, но почему то они этого не сделали.
Тэги:
Ответить:
Комментарии доступны только авторизированным пользователям
Похожие вопросы 1С
В этой группе 1С
- Не отображается дерево конфигурации
- «Комплектация номенклатуры», "Расчет себестоимости" - зависла сумма
- v7: SQLITE: Запрос с выборкой документа-владельца не отрабатывает как надо
- загадка: неснимаемая защита у ячейки
- v8: Как запретить выбирать определённые элементы справочника?
- Передача структуры через COM соединение
- пропадают базы из списков общих баз 1С
- УПП НДФЛ считает с копейками
- Как записать из 1с 8.2 в xml бинарные данные?
- СКД, как заставить вывести поле
- Как вылечить SQL базу? не запускается. после обновления из хранилища
- Как в отборе справочника указать без групп?
- MS SQL 2008 Восстановление из бэкапа. (Восстановление из копии..)
- Взять свободные остатки УТ11
- Как перебрать в цикле построчно область Табличного документа?
- Восстановление полного и разностного бэкапа 1С
- Автозаказ в 1С 8.2 УТ 11.1
- Делегирование в 1С:Документооборот.
- Непонятно как работает РежимВводаСтрок В Табличном поле Дерева
- Ищу чат в 1С 8.2