Sunteți pe pagina 1din 26

12

 Component Object Model (COM) permite


comunicarea interprocese si crearea dinamica de
obiecte in orice limbaj de programare care suporta
aceasta tehnologie.
 In esenta COM este o modalitate independenta de
limbaj de implementare a unor obiecte astfel incat
ele sa poata fi refolosite in medii diferite de cele in
care au fost scrise. COM permite reutilizarea
obiectelor fara a sti ce contin acestea.
 In .NET framework un obiect COM trebuie sa fie
inregistrat inainte ca el sa fie folosit.
 Inregistrarea se face ori folosin Visual Studio
2005, ori utilitarul Type Library Importer
(TlbImp.exe).
 Sa prespupunem ca avem obiectul COM numit
matlabGrafic.dll.
 Intai trebuie inregistrat in registy: Regsvr32
matlabGrafic.dll.
 Deschideti Visual Studio 2005 command prompt.
 Navigati la DLL-ul pe care doriti sa il importati.
 Scrieti tlbimp <numeDLL>.dll. Acest apel va crea un
assembly .NET cu numele <numeDLL>.dll.
 Daca doriti sa schimbati numele puteti folosii apelul>
tlbimp <numeDLL>.dll /out: <numeNouDLL>.dll
 In continuare importati noul assembly ca o
componenta .NET (Add Reference …)
 TlbImp.exe> importa obiecte COM
 TlbExp.exe> creaza obiecte COM din assembly-
uri .NET
 Regedit.exe
 Ildasm.exe> Interlediate Language Dissasambler.
 Regasm.exe> Assambly Registration Tool
 Sa presupunem ca am adauga la referinte un
obiect COM numit: Adobe Acrobat Reader 7.0
Document Browser si l-am instantiat.
 Folosirea lui e foarte simpla :
 axAcroPDF1.LoadFile(“fisiere.pdf”);
 axAcroPDF1.Print();
 Exceptiile aruncate in interiorul componentelor COM
pot fi prinse in exterior drept excepii
RuntimeWrapperException.
 RuntimeWrapperException mosteneste
System.Exception si adauga proprietatea
WrappedException.
 Atunci cand este aruncata o exceptie in obiectum
COM, .NET framework va arunca o exceptie proprie,
care va avea in proprietatea WrappedException
exceptia aruncata in COM.
 Componentele COM nu suporta
 Obiecte statice sau shared.
 Parametrii la constructor
 Supraincarcare
 Mostenirea devine inutila in unele cazuri
 Portabilitate (sistemele de operare fara registry nu pot sa
foloseasca obiecte COM).
 OBS:
 Parametrii nu pot fii transmisi decat prin referinta
 Atunci cand un parametru nu are nici o valoare va fi
transmis Type.Missing
 Pentru a crea o componenta compatibila COM
puteti urma urmatorii pasi:
 Pas1> Creati un .NET class library.
 Pas2> Deschideti dialog-ul Project Properties.
 Pas3> Dati click pe tab-ul Build.
 Pas4> Selectati optiunea Register For COM Interop
 Pas5> Build la assembly
 Puteti ascunde metode din .NET class library
COM-ului folosind atributul ComVisible.
 Pentru a va asigura compatiblitatea cu COM e bine
sa va asigurati ca urmatoarele cerinte sunt
indeplinite:
 Toate clasele trebuie sa aiba un constructor fara parametrii
 Toate tipurile expuse COM trebuie sa fie publice
 Toti membrii expusi COM trebuie sa fie publici
 Clasele abstracte nu vor putea fi consumate
 Dupa ce va asigurati ca respectati aceste criterii
puteti construii componenta COM ori folosin VS2005
ori utilitarul TlbExp.
 Pasi pentru deployment:
 Compilare:
 Csc /t:library ClasaVisibilaCom.cs
 Creare fisier TLB:
 Tlbexp ClasaVisibilaCom.dll /out: ClasaVisibilaComLib.dll
 Creati un script de resurse ClasaVisibilaCom.res in care
adaugati IDR_TYPELIB1 typelib “ClasaVisibilaComLib.tlb”
 Recompilati assembly-ul cu noul script resursa adaugat:
 Csc /t:library ClasaVisibilaCom.cs /win32res:
ClasaVisibilaCom.res
 .NET framework are posibilitatea de a folosii functii
din DLL-uri unmanaged (deci nici componenta COM,
nici .NET).
 Puteti astfel sa scrieti o functie in C++/Assembler si
sa o folositi foarte simplu in o aplicatie .NET.
 Un posibil avantaj este viteza. Unii algoritmi se pot
executa mult mai repede in cod unmanged decat in
cod managed.
 Dezavantaje ar fi durata mare a operatie de
conversie din tipuri managed in tipuri unamanged si
posibilitatea aparitiei memory leak-urilor.
 Cu Platform Invoke (P/Invoke) puteti apela
metode din dll-uril unamanged.
 Pentru a putea folosii p/invoke trebuie sa:
 Creati o metoda statica external cu numele functiei pe
care doriti sa o chemati
 Decorati cu atributul DllImport, unde speicificati ca
parametru numele dll-ului din care importati functia
 Apleati acea metoda in cod
 In general e bine sa construiti pentru DLL-urile pe
care le folositi clase care sa incapsuleze functiile
acestora, clase wrapper.
 Avantajele unei clase wrapper ar fi:
 Cei ce folosesc clasa nu vad nici o diferenta intre apelul de
cod managed si apelul de cod unmanaged.
 Dezvoltatorii nu trebuie sa isi mai aminteasca numele si
detaliile din codul unmanaged.
 Mai putine erori. Apelurile la P/Invoke sunt foarte
sensibibile la erori in parametrii deci e bine sa faceti
conversia o singura data bine si apoi sa refolositi.
 Multe conversii de tipuri de date din managed in
unmanaged se fac automat de catre runtime (ex: int,
char, char*).
 Atunci cand conversia se poate face in mai multe
tipuri se poate folosii atributul MarshalAs:
 Poate fi aplicat unei proprietati sau unui parametru, sau in
apelul de metode
 Primeste un singur parametru: tipul de date din care se
converteste. Acesta este un membru al enumerarii
UnmanagedType.
 Codul unmanaged in general se asteapta ca o
structura primita ca parametru sa aiba membrii
arantajati in o anumita ordine.
 In .NET framework runtime-ul poate optimiza
aranjarea membrilor unei structuri astfel incat
aranjarea membrilor in cod poate sa difere de cea ce
ar fi trimisa la un apel de functie unmanaged.
 Modalitatea prin care specificam modul de aranjare
al membrilor unei structuri este atributul
StructLayout.
typedef struct tagLOGFONT [StructLayout(LayoutKind.Sequential)]
public class LOGFONT
{ {
LONG lfHeight; public const int LF_FACESIZE = 32;
LONG lfWidth; public int lfHeight;
LONG lfEscapement; public int lfWidth;
LONG lfOrientation; public int lfEscapement;
LONG lfWeight; public int lfOrientation;
public int lfWeight;
BYTE lfItalic; public byte lfItalic;
BYTE lfUnderline; public byte lfUnderline;
BYTE lfStrikeOut; public byte lfStrikeOut;
BYTE lfCharSet; public byte lfCharSet;
BYTE lfOutPrecision; public byte lfOutPrecision;
BYTE lfClipPrecision; public byte lfClipPrecision;
public byte lfQuality;
BYTE lfQuality; public byte lfPitchAndFamily;
BYTE lfPitchAndFamily; [MarshalAs(UnmanagedType.ByValTStr,
TCHAR lfFaceName[LF_FACESIZE]; SizeConst=LF_FACESIZE)]
} LOGFONT; public string lfFaceName;
}
 Cea mai importanta proprietate din StructLayout
este LayoutKind.
 Aceasta se poate specifica in constructor si este
egala cu un membru al enumerarii LayoutKind:
 LayoutKind.Auto: Runtime-ul va aranja membrii structurii
asa cum doreste.
 LayoutKind.Sequential: Runtime-ul va mentime membrii
structurii in ordinea specificata de dezvoltator
 LayoutKind.Explicit: Runtime-ul va mentine membrii
structurii in ordinea specificata de dezvoltaror folosind
offset-uri de memorie
LayoutKind.Explicit presupune specificarea offsetului
in bytes pentru fiecare membru al structurii
 In codul unmanaged functiile callback sunt
implementate cu ajutorul pointerilor la functie.
 In codul managed functiile callback sunt
implementate cu ajutor delegatilor.
 Pentru a trimite un callback la cod unmanaged
trebuie deci creat un delegat cu prototipul
pointerului la functie.
 Performanta:Overhead-ul produs de conversia tipurilor
managed in unmanaged si invers poate scadea performanta
aplicatiei. Pot sa apara si memory leak-uri.
 Type safety: Codul unmanaged nu este typesafe.
 Securitatea codului: In codul unmanaged nu exista securitate
declarativa sau imperativa si o aplicatie care foloseste cod
unmanaged s-ar putea sa nu functioneze in un mediu partially
trusted.
 Versionarea: Cand scrieri o aplicatie managed puteti instala mai
multe versiuni ale aceleasi componente iar aplicatia poate alege
intre ele. Urmatoarele instalare ale acelelei aplicatii sau
componente nu vor afecta compotamentul deja existent.
Aplicatiile scrise in cod unmanaged nu au aceasta capabilitate.

S-ar putea să vă placă și