Editor Login | Register
Ekle

Root > Bilgisayar > Nesne Programlama
Runtime Compiling Uygulamasi - Nesne Programlama - Bilgisayar - Root
Tahkikat-ı Enderun
(Date : 24.12.2007 23:42:36)


Runtime Compiling Uygulamasi

Scripter

Merhaba, sanırım benim aklıma gelen bir çoğumuzunda aklına gelmiştir. Neden yazdığım programlarda script desteği olmasın, yani kullanıcılar kendi yazdıkları kodları programlarımızdan çalıştırabilirler mi. Tıpkı AutoCAD, Excel vs. gibi. .Net birçok konuda olduğu gibi bu iş içinde ihtiyaçlarımıza uygun ve çok faydalı bir namespace barındırıyor; System.CodeDom.Compiler namespace’si. Bu namespace sayesinde yazdığımız bir program çalıştığı sırada kodlarımız çalıştırabilir ve herhangi bir programa dahil edip oradan kullanabiliriz. Bu sayede kaynak kodların bulunduğu bir dosyayı script gibi kendi programlarımızda çalıştırabiliriz

Bunun ne faydası olur diyecek olursanız her şeyden önce esneklik derim. Unutulmamalıdırki artık programlama platformları programcıların değil kullanıcıların beklentilerini karşılamak için geliştiriliyor ve paket program kullanıcıları artık daha esnek programlar istiyorlar. Tıpkı Excel gibi bir makro yazıp bunu bir program gibi çalıştırabilirsiniz ya da AutoCAD’ de AutoLISP kullanarak kendi maliyet hesaplarınızı çıkartacak diyalog pencereleri, hesap fonksiyonları yazabilirsiniz. Böyle düşünecek olursak kendi programlarımızda da buna ihtiyaç duyduğumuz anlar olacaktır.

 

Bu kadar laftan sonra artık kodlamaya başlayalım. Örnek olarak bir VB.Net derleyicisi yazalım.

 

Resimdeki gibi bir form oluşturuyoruz,

 

·         ComboBox1

·         Button1

·         Button2

·         RichTextBox1

·         ListView1

 

 

 

Kullanılacak Namespaceleri projemize dâhil ediyoruz

 

C#.Net

text box: using system.io;
using system.reflection;
using system.codedom.compiler;
using microsoft.visualbasic;

 

 

VB.Net

text box: imports system.io
imports system.reflection
imports system.codedom.compiler
imports microsoft.visualbasic

 

 

ComboBox’ı derleme seçenekleri ile dolduruyoruz

 

C#.Net

text box: private void form1_load(object sender, system.eventargs e)
{
combobox1.items.add (

 

 

VB.Net

text box: private sub form1_load(byval sender as system.object, byval e as _
system.eventargs) handles mybase.load
        combobox1.items.add(

 

 

 

Button1’in (Çalıştır Butonu) click olayına yazılacak kodlar: der isimli ICodeCompiler tipinde bir değişken tanımlıyoruz bu değişken bizim derlemek istediğimiz kodlar için arabirim olacak ve der üzerinde vb kodlarını çalıştırabilecek bir derleyici oluşturuyoruz. VBCodeProvider kısmına dilersek CSharpCodeProvider yazarak, derleyicimizin C# kodlarını çalıştırmasını sağlayabiliriz,

 

C#.Net

text box: icodecompiler der;
der=new vbcodeprovider().createcompiler();

 

VB.Net

text box: dim der as icodecompiler
der=new vbcodeprovider().createcompiler

 

Derleyicimizin ihtiyaç duyduğu bazı parametreler olacak, derleme konumu, referans alınacak kaynaklar (Namespaceler) vs. gibi

 

C#.Net

text box: compilerparameters par=new compilerparameters();
par.referencedassemblies.add(

 

VB.Net

text box: dim par as new compilerparameters
par.referencedassemblies.add(

 

        

Combobox’ta seçtiğimiz seçeneğe göre derleme konumunu ve parametreler belirtiliyoruz.

 

C#.Net

text box: switch (combobox1.selectedindex)
{
	case 0: 
//derleme bellekte gerçekleştirilecek
		par.generateinmemory=true;
		break;
	case 1:
//bellekte oluşturulmayacak
		par.generateinmemory=false;
//exe dosya oluşturulacak
		par.generateexecutable=true;
//derlemek istediğimiz kod içerisindeki ilk çalıştırılacak olan main()
//yordamını bulunduğu sınıf
		par.mainclass=

        

 

VB.Net

text box: select case combobox1.selectedindex
case 0
‘derleme bellekte gerçekleştirilecek
par.generateinmemory=true
            case 1
‘bellekte oluşturulmayacak
par.generateinmemory=false
‘exe dosya oluşturulacak
par.generateexecutable=true
‘derlemek istediğimiz kod içerisindeki ilk çalıştırılacak olan main()
‘yordamını bulunduğu sınıf
par.mainclass=

 

 

Sıra geldi derlemeyi oluşturmaya. Bunu için derleyicimizin kaynak koddan derleme fonksiyonunu kullanacağız. Bu fonksiyon geriye bir sınıf döndürmektedir. Bu sınıf içinde, derleme sonuçlarıyla ve derlememizle ilgili bilgiler bulunmaktadır. Derlenen kodu çalıştırdığımız zaman bu bilgilere ihtiyacımız olacak o yüzden sonuçları CompilerResults tipindeki res isimli bir değişkende tutacağız. Ayrıca fonksiyona kaynak kodu string olarak göndereceğiz bunun içinde kod isimli değişkeni kullanacağız. Kod değişkeni değerini RichTextBox1’den yani kodlarımızı yazdığımız yerden alacak. Ayrıca fonksiyonumuz derleme anında ihtiyaç duyacağı parametreleride par isimli değişkenimize girdiğimiz değerlerden alacak

 

C#.Net

text box: string kod=richtextbox1.text; 
compilerresults res;
res=der.compileassemblyfromsource(par,kod);

 

VB.Net

text box: dim kod as string=richtextbox1.text
dim res as compilerresults
res=der.compileassemblyfromsource(par, kod)

 

Derleme sonuçlarına bakarak derleme sırasında hata olup olmadığına bakabilir eğer oluşmuşsa oluşan hataları öğrenebiliriz. Bunu için bir listview kullanacağız. res.Errors.HassErrors parametresi hata oluştuğunda true değerini alıyor. Hatalar Errors[x] ile sırayla çekeceğiz.

 

 

C#.Net

text box: listview1.items.clear();
if (res.errors.haserrors==true)
{
	int i;
	for(i=0;i<res.errors.count;i++)
	{
	listview1.items.add(res.errors[i].line.tostring());
	listview1.items[i].subitems.add(res.errors[i].errortext);
	listview1.items[i].subitems.add(res.errors[i].errornumber);
	return;
	}
}

 

VB.Net

text box: listview1.items.clear()
if res.errors.haserrors then
for i as integer=0 to res.errors.count – 1
listview1.items.add(res.errors(i).line.tostring)                listview1.items(i).subitems.add(res.errors(i).errortext)
listview1.items(i).subitems.add( res.errors(i).errornumber)
next
          exit sub
end if

 

        

 

Şimdide belirlediğimiz parametreler göre RAM’da veya bir Dosyaya yazarak derlediğimiz dosyadan bir Instance oluşturacağız, burada belirtmemiz gereken değer derlenen kodların Namespaces’i ve çalıştırmak istediğimiz Class. Yine bu fonksiyon geriye object tipte bir değer döndürecektir, bu değer eğer boşsa belirtilen Class bulunamamış demektir. Bunu kontrol ederek hata oluşmasını engelleyebiliriz.

 

 

C#.Net

text box: object cls;
cls=res.compiledassembly.createinstance(

 

VB.Net

text box: dim cls as object
cls=res.compiledassembly.createinstance(

 

InvokeMebmer metoduyla kodumuzu çalıştıracağız ama bundan önce invokMember metoduna ait parametreleri biraz açıklayayım:

 

String name                      : Çağrılacak method, özellik, veya Classa ait bir nesne adı

BindingFlags invokeAttr       : Belirtiğimiz ismin çağrılma yöntemi  

Object target                    : Çağrılan metodun bulunduğu nesne

Object[] args                    : Çağrılan fonksiyona gönderilecek parametreler

 

 

C#.Net

text box: try 
{
cls.gettype().invokemember(

 

 

VB.Net

text box: try
cls.gettype.invokemember(

 

 

Son olarak text dosyalarına yazdığımız kodları açmak için gerekli kodları yazalım

 

Aç… Butonu

 

C#.Net

text box: private void button2_click(object sender, system.eventargs e)
{
openfiledialog dlgopen=new openfiledialog();
	string srcfile;
	if (dlgopen.showdialog()==system.windows.forms.dialogresult.ok)
srcfile=dlgopen.filename.tostring();
system.io.streamreader a=new system.io.streamreader( srcfile,system.text.encoding.default);
richtextbox1.text=a.readtoend();
	}
}

 

 

VB.Net

text box: private sub button2_click(byval sender as system.object, byval e as system.eventargs) handles button2.click
dim dlgopen as openfiledialog=new openfiledialog
dim srcfile as string
if dlgopen.showdialog=system.windows.forms.dialogresult.ok then
srcfile=dlgopen.filename.tostring
dim a as system.io.streamreader=new system.io.streamreader(srcfile, system.text.encoding.default)
richtextbox1.text=a.readtoend
end if
end sub

 









Derecelendir
Kaynak Tahkikat-ı Enderun Tarafından yazılmış/derlenmiştir.
İçerik İhbarı
Bağlantılar: bilgininefendisi.net

Open Source Document Project AUP&TOS