wtorek, 10 lutego 2009

.NET i COM

Wcześniej opisałem już wspomniane w tytule technologie i wskazałem problemy i potencjalne rozwiązania używane podczas tworzenia oprogramowania, w którym należy wykorzystać komunikację pomiędzy kodem zarządzalny i niezarządzalnym. W przypadku interakcji komponentu COM i kodu powstałego w oparciu o technologię .NET należy poruszyć jeszcze dwie sprawy:

  • jak dostać się do obiektu COM z poziomu .NET Framework
  • jak udostępnić obiekt .NET Framework poprzez COM

Z pierwszą sytuacją mamy do czynienia, gdy chcemy napisać aplikację, która realizuje funkcjonalność klienta COM (np. klient OPC). Jest to prosty przypadek wystarczy zaimportować odpowiedni interfejs dostępny poprzez COM.

W tym celu definicję odpowiedniego interfejsu w języku C# poprzedzamy odpowiednimi atrybutami:

 [ComVisible(true), ComImport,
Guid("/*odpowiedni guid*/"),
InterfaceType( ComInterfaceType.InterfaceIsIUnknown )]

Interfejs powinien mieć definicję wszystkich potrzebnych funkcji. Zwykle informacje na temat, co to za funkcje znajdziemy w odpowiedniej specyfikacji. Do ich definicji następnie można już wykorzystać zasady marshallingu opisanego w poprzedniej części.

Oprócz definicji interfejsów należy zaimportować jeszcze pewne funkcje, np.:

CoCreateInstanceEx z biblioteki ole32.dll:

      [DllImport("ole32.dll")]
      private static extern void CoCreateInstanceEx(
          ref Guid         clsid,
          [MarshalAs(UnmanagedType.IUnknown)]
          object           punkOuter,
          uint             dwClsCtx,
          [In]
          ref COSERVERINFO pServerInfo,
          uint             dwCount,
          [In, Out]
          MULTI_QI[]       pResults);

Ewentualnie można również wykorzystać metodę CreateComInstanceFrom z klasy System.Activator.

Odrobinę trudniejsze jest udostępnienie komponentu napisanego w C# poprzez mechanizm COM (z takim przypadkiem mamy do czynienia chcąc napisać serwer OPC). W tym celu należy:

  1. Wybrać typy i procedury które mają być dostępne poprzez COM. Wszystkie one muszą być publiczne, typy (klasy) muszą mieć publiczny domyślny konstruktor (który jest jedynym konstruktorem, który może być wywołany poprzez COM).
  2. Ustawić odpowiednie atrybuty, które rozszerzą przenośność komponentu.
  3. Zarejestrować assembly wśród komponentów typu COM. Czynność ta może być wykonana w momencie tworzenia komponentu, instalacji lub później przy użyciu narzędzia Regasm.exe

Ciekawy artykuł na ten temat (rozwijające zagadnienia wspomniane w powyższych krokach) dostępny na stronach MSDN to: "Exposing .NET Framework Components to COM" (http://msdn.microsoft.com/en-us/library/zsfww439(VS.80).aspx).

1 komentarz:

  1. Bardzo rzetelnie opisujesz każde zagadnienie. Super jest ten wpis.

    OdpowiedzUsuń

Posty powiązane / Related posts