|
COM ve ActiveX Bileşenlerinin .NET'te Kullanılması |
|
Gönderiliyor lütfen bekleyin... |
|
|
Bu yazıda COM nesnelerinin
dotNET ortamında nasıl kullanabileceğimizi göreceğiz, bunun için VB6 ile yazılmış
basit bir COM nesnesini C# kullanarak .NET ortamına taşıyacağız. Bu taşıma işlemi
sırasında yapılması gerekenler adım adım incelenecektir. Ayrıca bu yazıda COM
teknolojisine dayanan ActiveX bileşenlerini .NET ortamında ne şekilde kullanabileceğimizi
de ele alacağız.
COM
nedir?
.NET ve COM ilişkisine geçmeden önce COM ve diğer standartlar hakkında bilgi
vermekte fayda var. COM, bir komponent geliştirme standartıdır. Öyleki COM standartlarına
uygun geliştirilen bütün komponentler COM nesnelerinin kullanılabildiği bütün
diller tarafından kullanılabilir. Zatan COM teknolojisinin geliştiricilere sağladığı
en büyük fayda dilden bağımsız olmasıdır. Günümüzde COM nesneleri geliştirebileceğimiz
bir çok geliştirme ortamı vardır. ATL ve VB bu ortamlara örnek olarak verilebilir.
COM teknolojisinin getirdiği yeniliklere rağmen COM geliştirmenin ve COM nesnelerinin
dağıtımı zor olduğu için çeşitli sorunlar ortaya çıkmıştır. Bu sorunlardan en
önemlisi meşhur "DLL-HELL" dediğimiz problemdir. Bu problem genellikle
aynı uygulamanın farklı versiyonlarına ait COM komponentlerinin sisteme kayıt
edilmesi ile meydana gelmektedir. .NETin altyapısında bulunan assmebly versiyonlama
sayesinde bu problem tamamen ortadan kalkmıştır.
COM komponentleri ile ilgili diğer önemli bir sorun da, COM komponentlerini
kullanmadan önce Registery bölgesine kayıt edilmek zorunda olmasıdır. Registera
kaydedilen COM nesnelerine atanan bir anahtar(GUID) ile çalışma zamanında COM
nesnesi ayrıştırılır. .NET komponentlerini kullanmadan önce herhangi bir kayıt
işlemi yapmaya gerek yoktur.
Herşeye rağmen .NET eski komponentleri kullanmak için çeşitli mekanizmalar sunmaktadır.
Bu yazının amacıda zaten bu mekanizmayı göstermektir.
RCW
(Runtime Callable Wraper)
.NET ve COM mimarisi biribirinden tamamen farklıdır. Bu da .NET ortamından COM
nesnelerine direkt erişmeyeceğimz anlamına gelir. .NET ortamında COM nesnelerine
erişebilmek için, bu nesnelere yönelik RCW komponentlerini oluşturmamız gerekir.
RCW, .NET ile COM arasında bir arayüz gibidir. Oluşturulan RCW komponentine
normal .NET komponenti gibi erşimek mümkündür. Biz aslında .NET ile RCW komponentine
erişmiş oluyoruz. COM ile olan bağlantıyı ise RCW sağlar. Bunu .NETin bize
sunduğu bir hizmet olarak düşünebiliriz.
RCW, yönetilen kod(managed code) ile yönetilmeyen kod(unmanaged) arasında bağlantıyı
sağlar diyebiliriz. Burada yönetilen kod .NET kodları yönetilmeyen kodlar ise
COM komponentinin kodlarıdır. Bu ilişkiyi kafanızda daha iyi canlandırmak için
aşağıdaki şekli inceleyin.
Daha fazla kavram kargaşısına girmeden bu yazıda üzerinde duracağımız mekanizmayı
özetleyelim: Birazdan anlatacağım yöntemlerle oluşturacağımız assembly lere
referans vererek .NET ortamından bir COM nesnesine RCW üzerinden nasıl erişebileceğimizi
göreceğiz.
COM komponentlerini saran(wrap) ve .NET ortamından kendisine referans verebileceğimiz
assemblyleri hazırlamak için iki seçeneğimiz var. Bunlardan birincisi komut
satırından kullanılan TlbIMP.exe(Type Library Importer) aracı diğeri ise Visual
Studio.NET geliştirme aracıdır.
Şimdi adım adım bir COM komponentinin .NET ortamında nasıl kullanıldığını görelim.
Bu işlemleri görebilmek için elbette bir COM kompnentine ihtiyacımız olacak.
Bu yazıda sisteminizde var olan COM komponentleri kullanabileceğiniz gibi VB
6.0 yada ATL kullanarak yeni bir COM komponenti de oluşturabilirsiniz. Ben herşeyin
daha anlaşılır olabilmesi için VB 6.0 ile basit bir ActiveX Component projesi
açıp iki metodu olan bir komponent yazdım. Çünkü VB 6.0 ile COM uygulamaları
geliştirmek oldukça kolaydır. Siz benim yaptığım komponentin aynısını isterseniz
C++ kullanarak ATL ile de oluşturabilirsiniz. Yada daha önceden sisteminizde
kayıtlı olan COM komponentini kullanabilirsiniz. Sisteminizde kayıtlı olan COM
komponentlerini görmek için Visual Studio.NETi kullanabilirsiniz. Zira Project
menüsünden Add Reference menüsünü seçtikten sonra çıkan pencereden COM sekmesini
seçtiğinizde sisteminizde kayıtlı olan COM nesneleri hakkında bilgi edinebilirsiniz.
VB 6.0da yeni
bir proje açtıktan sonra, projeye DortIslem isimli bir "Class Module"
ekleyin. DortIslem isimli Class Moduleüne aşağıdaki kodları yazıp projeyi derleyin.
Public Function
Topla(ByVal Sayi1 As Long, ByVal Sayi2 As Long) As Long
Topla =
Sayi1 + Sayi2
End Function
Public Function Carp(ByVal Sayi1 As Long, ByVal Sayi2 As Long) As Long
Carp = Sayi1 * Sayi2
End Function
|
Oluşturduğunuz
bu projeyi File menüsünden Make VbCOM.dll i seçerek COM komponentinin oluşmasını
sağlayın. (VbCOM oluşturduğum projenin adıdır.)
Diğer COM istemcilerinin erişimini sağlayabilmemeiz için registera kayıt etmemiz
gerekir. Bunun için komut satırına
regsvr32 VbCOM.dll
yazın. Eğer "DllRegisterServer in VbCOM.dll succeeded" mesajı verildiyese
kayıt işlemi başarıyla bitmiş demektir.
Visual
Studio.NET ile COM bileşenlerine erişmek
Oluşturulan bu
COM tabanlı dll dosyasını .NET projelerinde direkt kullanamayız. Bunun için
bu COM nesnesini sarmalayan(wrapper) sınıfı oluşturmamız gerekir. Daha öncede
dediğimiz gibi bunun iki yöntemi vardır. İlk yöntem oldukça basittir. Yeni bir
Visual Studio.NET projeis açın. Project menüsünden Add Referenceı seçip COM
sekmesine geldiğinizde sisteminize kayıt edilmiş COM bileşenlerini görürsünüz.
Aşağıdaki ekran görüntüsünden de görüldüğü üzere bizim oluşturduğumuz VbCOM.dll
bileşeni de eklenmiştir.
Project1 isimli COM bileşenine referans verdikten sonra artık projemizde Project1
isim alanı(namesapce) ile bu bileşenin sınıflarını rahatlıkla kullanabiliriz.
Project1 VB 6.0 ile oluşturduğum projenin adıdır. Varsayılan olarak bu isim
alanı ile oluşturulmuştur. Bu ismi istediğiniz gibi değiştirebilirsiniz. COM
bileşenini sarmalayan(wrapper) sınıfı Visual Studio.NET bizim için otomatik
oluşturduğu için bu COM bileşeni artık bizim için .NET bileşeninden farklı değildir.
Şimdi isterseniz Project1 isim alanında bulunan yapılara bakalım.
Yukarıdaki yapıda biraz tuhaflık olduğunu düşünebilirsiniz. Çünkü DortIslem
isimli sınıf yerine DortIslemClass isimli bir sınıf var. Bu her zaman bu şekilde
oluşur. DortIslem ise COM nesnesindeki arayüzü belirtmektedir. Bu arayüz orjinal
COM bileşenindeki GUIDi taşır. DortIslemClass, bu arayüzü uygulayan bir sınıftır.
Bu yüzden nesneleri DortIslemClass sınıfını kullanarak oıluşturacağız. Aşağıdaki
gibi "islem" isimli bir nesne oluşturup DortIslemClass sınıfının üye
elemanlarına bakalım.
Project1.DortIslemClass
islem = new Project1.DortIslemClass();
|
Not: Project1 isim
alanını using deyimi ile programın başına eklerseniz nesne oluştururken isim
alanını kullanmanıza gerek yoktur.
"islem" nesnesi üzerinden DortIslemClass sınıfının üye alamanlarına
bakacak olursak:
Yukarıdaki ekran görüntüsünden de gördüğünüz gibi COM bileşenindeki metotların
yanısıra .NETteki Object sınıfının metotları olan Equlas(), ToString() gibi
metotlarda eklenmiştir. Bunları COM nesnesinde olmayan ancak RCW tarafından
.NET ortamı için eklenen metotlardır. Bu ekran görüntüsünde önemli olan diğer
bir konu ise Topla() ve Carp() metotlarının parametrik yapısdır. Hatırlarsanız
VB 6.0 ile oluşturduğumuz bu metotların parametreleri ve geri dönüş değerleri
long türündendi. Halbuki sarmalayıcı(wrapper) sınıf içinde bunlar int türüne
dönüştürülmüştür. Bu da COM türlerinin, .NET e uygun türlere dönüştürüldüğü
anlamına gelmektedir. Diğer türlerin ne şekilde dönüştürüldüğünü görmek için
VB 6.0 da oluşturduğunuz COM bileşeninde değişiklikler yapın.
DortIslemClass sınıfı aşağıdaki program ile test edebilirsiniz. Herhangi bir
hata almadıysanız COM bileşenini .NET ortamında kullanmış oldunuz demektir.
using
System;
using
Project1;
class
Class1
{
static void Main()
{
DortIslemClass
islem = new DortIslemClass();
Console.WriteLine(islem.Topla(5,6));
Console.WriteLine(islem.Carp(5,6));
}
}
|
TlbImp.exe
ile COM bileşenlerine erişmek
Herkesin Visual
Studio.NET geliştirme aracına sahip olma şansı olmayabilir. Bu yüzden Microsoft
komut satırından çalışan çeşitli kullanışlı araçlar sunmuştur. Bu araçlarıdan
biri de TlbImp.exe(Type Library Importer) aracıdır. Bu program ile COM bileşenleri
içinde bulunan sınıflar .NET ortamından referans verilebilecek hale getirilir.
Yani COM bileşenini sarmalayan(wrap) RCW bileşeni oluşturulur. Aşağıdaki erandan
TlbImp.exe programının ne şekilde kullanıldığı görülmektedir.
TlbImp programı
3 argüman ile kullanılmıştır. /namesapce:CsNedir argümanı ile oluşturulacak
assemblyye ilişkin isim alanını belirtir. Bu kullanımda varsayılan isim alanı
yerine CsNedir seçilmiştir. Eğer bu argüman kullanılmasaydı assemblynin varsayılan
isim alanı olan Project1 olacaktı. /out:VbCOM_RCW argümanı ile COM bileşenini
sarmalayan assemblynin hangi isimle kaydedileceği belirtilmektedir. /verbose
argümanı ise yapılan işlemler hakkında detaylı bilgi almak amacıyla kullanılır.
Bu argümanı kullanmanız gerekmez. Son olarak COM tabanlı dll dosyasının ismi
yazılmıştır. Bu dosyanın ismide VbCOM.dll dir. TlbImp aracı ile kullanılabilecek
diğer argümanların listesini görmek için komut satırına
tlbimp /?
yazın.
TlbImp ile oluşturulan VbCOM_RCW.dll assemblysine ILDASM aracı ile baktığınızda
aşağıdaki ekran görüntüsünü elde etmelisiniz.
Yukarıdaki görüntüden de anlaşıldığı gibi Visual Studio.NETin otomatik oluşturduğu
sarmalayıcı sınıflar ve arayüzler, TlbImp aracının oluşturdukları ile aynıdır.
Şimdi sıra geldi oluşturduğumuz VbCOM_RCW.dll assemblysini test etmeye. Öncelikle
aşağıdaki programı yazın.
//Test.cs
using
System;
using
CsNedir;
class
Class1
{
static void Main()
{
DortIslemClass
islem = new DortIslemClass();
Console.WriteLine(islem.Topla(5,6));
Console.WriteLine(islem.Carp(5,6));
}
}
|
Komut satırından bu
programı aşağıdaki gibi derleyin.
csc /r:VbCOM_RCW.dll Test.cs
Eğer herhangi bir hata yapmadıysanız COM bileşeni kullanan .NET programınız hazır.
Programı çalıştırdığınızda ekrana
11
30
yazması gerektiğini tahmin etmiş olmalısınız.
Not: TlbImp ile
oluşturduğumuz DortIslemClass sınıf yönetilen kod kapsamına girdiği için kontrolü
CLR tarafından sağlanmaktadır. Yani gereksiz nesne toplayıcısı(garbage collection)
ile "islem" nesnesi bellekten kaldırılır.
.NETte
ActiveX Bileşenlerini Kullanmak
ActiveX kontrolleri genellikle grafik arayüzü içeren COM tabanlı bileşenlerdir.
Grafik arayüzü olmayan ActiveX kontrollerinin olabileceğinide unutmayın. ActiveX
kontrolleri .ocx uzantılı dosyalardır. ActiveX kontrollerinin .NETte kullanılması
yukarıda anlattığım diğer COM bileşenlerinin kullanılması ile aynıdır. Değişen
tek şey kullanacağımız aracıın farklı olması ve oluşturulan .NET sınıflarının
grafik arayüzü içermesidir.
COM tabanlı ActiveX bilşenlerine .NET projelerinden referans verilebilecek hale
getrimek için AxImp.exe(ActiveX Importer) aracı kullanılmaktadır. Bu
yazıda örnek olarak COM tabanlı olan Windows Media Playerı bir form üzerinde
göstermek için gereken adımları göstereceğim. Bu yüzden Windows Media Playerı
temsil eden msdxm.ocx dosyasını kullanacağım.
Not: msdxm.ock dosyası X:/WINNT/System32 dizini altında bulunmaktadır.
AxImp aracını komut satırından aşağıdaki gibi çalıştırın.
AxImp aracı iki tane assembly oluşturmuştur. MediaPlayer.dll assemblysi grafik
arayüzü içermeyn ama .NET paltformundan referans verebileceğimiz bir assemblydir.
AxMediaPlayer.dll ise Form tabanlı(Windows Form, ASP.NET Form) projelerde kullanabileceğimiz
grafik arayüzü içeren kontrolleri temsil eder. Bu assemblyye .NET projelerinden
referans verdiğimizde MediaPlayer nesnesine bir kontrol gibi erişebiliriz.
Bir Windows Form uygulaması yaparak AxMediaPlayer assemblysindeki kontrolü
test edelim. Test işlemi için bir video(mpeg) dosyasına ihtiyacımız olacak.
Kendinize herhangi bir video dosyası belirledikten sonra aşağıdaki programı
bir metin editöründe yazın.
//MPFrom.cs
using
System;
using
System.Drawing;
using
System.Collections;
using
System.ComponentModel;
using
System.Windows.Forms;
public
class
Form1 : Form
{
private AxMediaPlayer.AxMediaPlayer
axMediaPlayer1;
public
Form1()
{
axMediaPlayer1
= new AxMediaPlayer.AxMediaPlayer();
axMediaPlayer1.Location
= new Point(8,8);
axMediaPlayer1.Name =
"axMediaPlayer1";
axMediaPlayer1.Size
= new Size(286,255);
Controls.AddRange(new
Control[]
{axMediaPlayer1});
Name
= "Form1";
Text
= ".NET Media Player";
Load
+= new EventHandler(Form_Load);
}
[STAThread]
static
void Main()
{
Application.Run(new
Form1());
}
private
void Form_Load(object sender, EventArgs
e)
{
axMediaPlayer1.FileName
= @"J:/Musti3D/Birds.mpeg";
}
}
|
Kodu yazdıktan
sonra komut satırından aşağıdaki gibi derleyin.
csc /t:winexe /r:D:/WINNT/System32/AxMediaPlayer.dll MPForm.cs
Not: /r: argümanı ile msdxm.ocx dosyasından AxImp ile oluşturduğunuz assemblyye
referans veriyoruz.
Programı çalıştırdığımızda aşağıdaki gibi bir ekran görüntüsü ile karşılaştığımızı
görürüz.
Visual Studio.NET ortamından ActiveX kontrollerini kullanmak ise oldukça kolaydır.
ToolBox penceresine sağ tıklayıp "Customize Toolbox" menüsünü seçtikten
sonra karşınıza çıkacak pencereden "COM Components" sekmesini seçip
istediğiniz ActiveX kontrolüne referans verebilirsiniz. İlgili ActiveX kontrolünü
seçip OK düğmesine bastıktan sonra ToolBox penceresine ActiveX bileşenini temsil
eden yeni bir kontrol eklendiğini görürsünüz.
Sonuç: .NET sunduğu yeni mimarisinin yanısıra eski teknolojileride kullanma
imkanı vermesi .NET platformuna geçmek için yeterli bir sebeptir.
Bu konu ile ilgili bir sonraki yazıda .NET bileşenlerinin COM istemcileri tarafından
nasıl kullanılabileceğini ele alacağım.
Kaynaklar
MSDN Yardım Dökümanları
Developing Applications with Visual Studio.NET (Richard Grimes)
Makale:
COM ve ActiveX Bileşenlerinin .NET'te Kullanılması C#, Visual C# ve .NET Sefer Algan
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|