Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Создание компонента COM на C#  (Прочитано 13665 раз)
0 Пользователей и 1 Гость смотрят эту тему.
RomCom
Опытный

ru
Offline Offline
Пол: Мужской

WWW
« : 21-05-2006 14:02 » 

Привет всем!
кто-нибудь делал компоненты COM на C# (VS2005 или BDS2006)?
Перерыл горы интернет сайтов (в том числе MSDN). Из этого вороха только крупицы с реальными примерами, но практически все сводятся к отрывкам кода. А полного (работающего) описания так и не нашел.
Вот один из примеров:
Код:
namespace TestComLib
{
    [Guid("AD0DC746-F175-4b0b-B92B-03C2893498FC")] //это моя вставка в оригинале использовался файл ключ .snk
    public interface ITestComponent
    {
        int Mul(int First, int Second);
    }

    [Guid("CBEB5433-002A-4fdf-AD04-E9BD9EEE604A")] //тоже отсебятина :)
    public class TestComponent : ITestComponent
    {
        public TestComponent()
        {
           
        }

        public int Mul(int First, int Second)
        {
            return First * Second;
        }

        public String About
        {
            get
            {
                return "This component wrote on C#";
            }
        }
    }
}
Компилирую. Создаю TestComLib.tlb - "tlbexp /win32 TestComLib.dll".
Пытаюсь зарегить "regasm /tlb TestComLib.dll". В итоге ошибка "Failed to load....is not valid .NET assembly"
Что я сделал не так?

P.S. Честно говоря не пойму почему до сих пор MS не догадалась сделать удобный интерфейс для инсталляции/деинсталляции COM компонентов на этапе разработки. Свихнутся можно если при отладке постоянно набивать в командной строке "tlbexp ........ regasm" Жаль
« Последнее редактирование: 22-05-2006 02:27 от RomCom » Записан

R.O.M.C.O.M.: Robotic Operational Mathematics and Ceaseless Observation Machine
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 21-05-2006 19:16 » 

Кхм, так ведь COM не под .NET работает, это неуправляемый код. Посмотри в направлении Interop Marshaling. Если вообще возможно написать COM-объект с использованием .NET, то определённо он будет использовать мост между COM и .NET. Насколько я понимаю, тебе нужен сервер с управляемым кодом и COM-клиент к нему, предоставляющий интерфейс всей системы.
« Последнее редактирование: 21-05-2006 19:18 от dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RomCom
Опытный

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 21-05-2006 23:25 » 

dimka, привожу цитату из одной статьи:
Цитата
CoCreateInstance создает в памяти не сам компонент, а библиотеку mscoree.dll, которая является средой исполнения .NET. Эта библиотека предоставляет интерфейс фабрики классов IClassFactory для создания компонентов. При попытке создания компонента через этот интерфейс среда исполнения автоматически создаёт нужный компонент .NET и предоставляет его COM-совместимый интерфейс. При обращениях из среды COM, .NET берет на себя заботу о маршалинге данных их среды в среду.
Так что вроде как получается что можно. Вопрос в том как все сделать правельно в связке "код - компиляция - регистрация СОМ".
Полностью статья здесь: Использование .NET компонентов при помощи COM
« Последнее редактирование: 21-05-2006 23:40 от RomCom » Записан

R.O.M.C.O.M.: Robotic Operational Mathematics and Ceaseless Observation Machine
RomCom
Опытный

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 22-05-2006 02:39 » new

С регистрацией разобрался. Оказывается VS2005 уже все зделала сама. У меня ведь стоит галочка в настройках проекта "Register for COM interop" Улыбаюсь

Теперь другая пролема, с подключением.
Код:
//Описываю интерфейс
namespace TestComLib
{
    [Guid("AD0DC746-F175-4b0b-B92B-03C2893498FC"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface ITestComponent
    {
        int Mul(int First, int Second);
        int Square { get; set; }
        String About { get; }
    }
    [ComImport, Guid("CBEB5433-002A-4fdf-AD04-E9BD9EEE604A")]
    class TestComponent
    {
    }
..........
//Пытаюсь подключится
private void button3_Click(object sender, EventArgs e)
{
            TestComLib.TestComponent tc = new TestComLib.TestComponent(); //Ошибка
            TestComLib.ITestComponent ic = (TestComLib.ITestComponent)tc;
            label1.Text = ic.About;
}
Текст ошибки:
Цитата
Unable to cast object of type 'TestComLib.TestComponent' to type 'TestComLib.TestComponent'.
т.е. несовпадение типов или пространства имен. Как тогда правельно?
Через позднее связывание таже ошибка:
Код:
string sAppProgID = "TestComLib.TestComponent";
            object oTestCom = null;
            try
            { oTestCom = Marshal.GetActiveObject(sAppProgID); }
            catch
            { oTestCom = Activator.CreateInstance(Type.GetTypeFromProgID(sAppProgID)); }
       .................
           //Этот метод проходит без проблем
            label1.Text = (string) oTestCom.GetType().InvokeMember("About",
                 BindingFlags.GetProperty, null, oTestCom, null);
         ...................
            //такой способ не проходит, а как раз его то и хотелось бы реализовать
            TestComLib.TestComponent i = (TestComLib.TestComponent)oTestCom;
            TestComLib.ITestComponent mc = (TestComLib.ITestComponent)i;
            label1.Text = mc.About;
« Последнее редактирование: 19-12-2007 18:30 от Алексей1153++ » Записан

R.O.M.C.O.M.: Robotic Operational Mathematics and Ceaseless Observation Machine
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines