<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>Diyezon &#187; kod çevirme</title> <atom:link href="http://www.diyezon.com/tag/kod-cevirme/feed/" rel="self" type="application/rss+xml" /><link>http://www.diyezon.com</link> <description>programlama sanatı...</description> <lastBuildDate>Tue, 24 Jan 2012 00:13:26 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>C / C++ &#8216;dan Delphi&#8217;ye Kod Çevirme Klavuzu (1)</title><link>http://www.diyezon.com/c-den-delphiye-kod-cevirme-klavuzu-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=c-den-delphiye-kod-cevirme-klavuzu-1</link> <comments>http://www.diyezon.com/c-den-delphiye-kod-cevirme-klavuzu-1/#comments</comments> <pubDate>Thu, 19 Feb 2009 02:30:30 +0000</pubDate> <dc:creator>Fatih Tolga Ata</dc:creator> <category><![CDATA[Delphi]]></category> <category><![CDATA[C]]></category> <category><![CDATA[header]]></category> <category><![CDATA[kod çevirme]]></category><guid
isPermaLink="false">http://www.diyezon.com/?p=57</guid> <description><![CDATA[Özellikle işe yarar bir kütüphane bulduğunuz zaman eğer yoksa hemen Delphi sürümlerini araştırırız. Çoğu zaman &#8220;Delphi port&#8221; ismiyle, kütüphanelerin Delphi versiyonlarına erişebiliriz. Eğer Delphi versiyonlarını bulamazsak, iş başa düşmüş demektir.  Kütüphaneler bir çok dilde olabilirler. Fakat genel manada en çok C++ veya C kodlarının adaptasyonu ve çevrilmesi programcıları zorlayabilmektedir. Bu yazımızda C / C++ ve [...]]]></description> <content:encoded><![CDATA[<p
style="text-align: justify;">Özellikle işe yarar bir kütüphane bulduğunuz zaman eğer yoksa hemen Delphi sürümlerini araştırırız. Çoğu zaman &#8220;Delphi port&#8221; ismiyle, kütüphanelerin Delphi versiyonlarına erişebiliriz. Eğer Delphi versiyonlarını bulamazsak, iş başa düşmüş demektir.  Kütüphaneler bir çok dilde olabilirler. Fakat genel manada en çok C++ veya C kodlarının adaptasyonu ve çevrilmesi programcıları zorlayabilmektedir.</p><p
style="text-align: justify;">Bu yazımızda C / C++ ve Delphi gramer bilgisi vermek yerine, daha çok C / C++ kodlarını en doğru şekilde Delphi&#8217;ye nasıl adapte edebileceğimizi göreceğiz. Yapacağımız işlem sadece bire bir kod çevirisi olmayacak. Yeri geldiğinde hiç bir kod çevirmeden sadece orjinal kütüphaneyi Delphi programımızın içine gömebileceğiz.</p><p
style="text-align: justify;">Eğer siz de, ister derlenmiş olsun, ister açık kaynak kodlu olsun, bir C / C++ kütüphanesini Delphi&#8217;ye nasıl çevirebileceğimizi merak ediyorsanız buyurun beraber yazımıza giriş yapalım.</p><p><span
id="more-57"></span></p><h1>Giriş</h1><p
style="text-align: justify;">C / C++ &#8216;dan Delphi&#8217;ye kod çevirme derken ilk akla gelen, binlerce satırlık C kodlarını teker teker uğraşıp Delphi olarak yazmak gelecektir. Halbuki bu en son tercihimiz olması gerekmektedir. İlerleyen bölümlerde de göreceğimiz gibi, Delphi derleyicisinin hünerli parmakları bizi bir çok dertten kurtarmaktadır. Yine de bütün kodları baştan çevirmek gibi bir derdin altına girmek isterseniz bu makale size bir başlangıç noktası olacaktır.</p><p
style="text-align: justify;">Hemen kodlara dalmak gerçekten gerekli mi? Kesinlikle gerekli değil. Çünkü bizim uğraştığımız şey, önceden birileri tarafından yapılıp internet üzerinde dağıtılıyor olabilir. Bu yüzden ilk yapacağımız işlem bir &#8220;Delphi port&#8221; bulmamız gerekmetedir.</p><p
style="text-align: justify;">Mesela şuanda en hızlı ve en stabil xml kütüphanesi kabul edilen libxml2 kütüphanesini kullanmak istediğimizde, hemen kodları çevirmeye kalkmak yerine bir Delphi port bulmamız en akıllıca işlem olacaktır. Ki bu kütüphanenin başlık dosyaları zaten sourceforge üzerinde dağıtılmaktadır.</p><p
style="text-align: justify;">Bu makalede, C objelerinin kullanımı, C veri tiplerinin Delphi&#8217;deki karşılıkları, C başlık (header .h) dosyalarının Delphi&#8217;ye çevrilmesi gibi bir çok konu bulacaksınız. Bu bilgiler ile istediğiniz bir C kütüphanesini korkmadan Delphi&#8217;ye adapte edebilirsiniz.</p><p
style="text-align: justify;">Bu makalede çok fazla C / C++ bilgisi gerekli mi? Gerekli olsa bu makaleye ihtiyaç duymazdınız. Fakat çok  az da olsa C / C++ gramerine aşinalığınız olmak zorunda. En basit olarak bir bir fonksiyon nasıl tanımlanır, bir değişken nasıl tanımlanır, bir pointer nasıl atanır, bunları bilmeniz gerekmektedir.</p><h1>Fonksiyon Çağırım Mekanizmaları</h1><p
style="text-align: justify;">Bir çinli ile anlaşabilmek için bir tercüman tutmanız gerekti. Fakat çok aramanıza rağmen çinli bir tercüman bulamadınız. Bunun yerine bir birine benziyor diye kalkıp, japonca bir tercüman tuttunuz. Çinli olan birisi ile ne kadar anlaşabilirsiniz. Her ne kadar bize &#8220;benzer&#8221; gibi gözükse de iki dil bir birinden farklı dildir. Bu örneği şimdi göreceğimiz konuya hazırlamak için verdim. Bu misalden hakikate şu şekilde geçebiliriz. Derlenmiş olan her bir kütüphanedeki fonksiyonlar belli bir dili konuşmaktadırlar. Bu konuştukları diller görünüşte bir birlerine benzeseler de, ayrıntıda bir birlerinden farklıdırlar. Bu konuşulan dillere fonksiyon mekanizmaları ya da ingilizce terim olarak &#8220;calling conventions&#8221; denilmektedir. Eğer kullanacağınız fonksiyon farklı bir dili kullanıyor ve siz de fonksiyonu farklı bir dil ile çağırıyorsanız muhtemel hatalar ile karşılaşacaksınız. Bu yüzden ilk öğreneceğimiz konu bu olmalıdır.</p><p
style="text-align: justify;">Direk olarak çağırım mekanizmalarının delphi karşılıklarını vermek yerine az da olsa bir kaç özelliklerinden bahsetmek istiyorum. Çünkü hangi çağırımı nerede ne için kullanacağımızı bilmemiz şarttır.</p><p
style="text-align: justify;">Şu an literatürde en çok kullanılan 4 çeşit fonksiyon çağırım mekanizması vardır. Bunların ne olduğunu ayrıntısı ile anlatan <a
href="http://www.diyezon.com/index.php/2007/06/23/fonksiyon-cagirim-mekanizmalari/" target="_blank">buradaki</a> makalemize göz atabilirsiniz. Hatta okumadı iseniz bir göz gezdirmenizi şiddetle tavsiye ediyorum. Biz burada bu mekanizmaların çalışma şekillerinden çok işimize yarayan kısmını anlatmaya çalışacağız. Ama linkini verdiğim makalede bunların çalışma şekillerini ayrıntılı bir şekilde bulabilirsiniz.</p><p
style="text-align: justify;">Birinci olarak göreceğimiz çağırım mekanizması <strong>register </strong>çağırımıdır. Delphi varsayalın olarak bütün fonksiyon ve metodlarda bu çağırımı kullanmaktadır. Normalde Dehlpi&#8217;de &#8220;register&#8221; ayrılmış kelimesini fonksiyon ya da metodun sonuna eklemekle, fonksiyon ya da metodu bu çağırım için ayarlamış oluruz. Fakat varsayılan olarak kullanıldığı için bunu yazmanıza gerek yoktur:</p><pre class="brush: delphi">procedure RegisterCagirimliProcedure; register;</pre><p
style="text-align: justify;">Fonksiyon çağırım mekanizmaları ile ilgili yazıyı okuduysanız en verimli ve performanslı çağırımın bu olduğunu biliyorsunuzdur. Bu mekanizma ilk olarak Borland tarafından geliştirilip C++ Builder ve Delphi derleyicilerinde kullanıldı. Şu anda bildiğim bütün C / C++ derleyicileri bu çağırımı desteklemektedir. C / C++ derleyicilerinde bu çağırım<strong> __fastcall</strong> olarak isimlendirilmektedir.</p><p
style="text-align: justify;">Her ne kadar en hızlı çağırım __fastcall yani register olsa da ve çoğu derleyici tarafından desteklense de, belki de alışkanlıklardan dolayı, C / C++&#8217;da pek kullanılmamaktadır. Genelde Linux ve Windows&#8217;da ileride gelecek olan başka çağırımlar kullanılmaktadır.</p><p
style="text-align: justify;">__fastcall yani register çağırımları, Microsoft&#8217;uın derleyicilerinde <strong>__msfastcall</strong> olarak başka bir biçimi de almıştır. Fakat şu anda Delphi bu çağırımı desteklememektedir. Umarım ilerideki Delphi derleyicilerinde bunu görebiliriz. Fakat bu çağırım __fastcall kadar bile yaygın ve fazla kullanılmadığı için şu anda anlattığımız çevirim işlemi için çok da önemli değil. Hatta, eğer bir kütüphane bir çok dili desteklemek gibi bir gayesi varsa __fastcall çağırımını da desteklememektedir.</p><p
style="text-align: justify;">Kısacası bu çağırımı delphi&#8217;ye aktarmak için hiç bir şey yapmamız gerekmiyor. Çünkü delphi bunu varsayılan olarak kullanıyor. Mesela aşağıdaki C fonksiyonunu delphi&#8217;ye çevirelim:</p><pre class="brush: c++">__fastcall int birFonksiyon(int i);</pre><pre class="brush: delphi">function BirFonksiyon(i: Integer): Integer;</pre><p
style="text-align: justify;">İkinci çağırım mekanizmamız <strong>__pascal</strong> yada delphi&#8217;de <strong>pascal</strong> çağırımıdır. Ki bu çağırım Win 3.1 zamanından kalma eski bir çağırımdır. Bu yüzden eğer karşılaşırsanız yapmanız gereken __pascal yerine pascal yazmalısınız.</p><p
style="text-align: justify;">Üçüncü çağırım mekanizmamız <strong>__stdcall</strong> ya da delphi&#8217;de <strong>stdcall</strong> çağırımıdır. Bu çağırım, Windows işletim sisteminin varsayılan çağırım mekanizmasıdır. Eğer windows&#8217;a ait bir DLL&#8217;i kullanacaksak, bilinki %99 stdcall olarak tanımlanmıştır. __stdacall çağırımı derleyicilerde çeşitli takma adlar ile kullanılmaktadır. Genelde &#8220;WINAPI&#8221; kelimesi __stdcall için kullanılmaktadır. Mesela aşağıdaki Windows API&#8217;sinden bulunan fonksiyonu şöyle çevireceğiz:</p><pre class="brush: c++">WINAPI BOOL ReleaseCapture(VOID);</pre><pre class="brush: delphi">function ReleaseCapture: Boolean; stdcall;</pre><p
style="text-align: justify;">Yardım dosyalarında bu fonksiyonun başında WINAPI ya da __stdcall ifadesini görmesek de, biliyoruz ki bu bir Windows fonksiyonudur. Öyleyse bu fonksiyon stdcall çağırımıdır. Bu çıkarım ile hem delphi hem de C kodunda bu çağırımı belli ettim.</p><p
style="text-align: justify;">Dördüncü ve son çağırımımız ise <strong>__cdecl</strong> ya da delphi&#8217;de <strong>cdecl</strong> çağırımıdır. Bu çağırım C / C++ derleyicilerinin varsayılan çağırımıdır. Eğer C dosyalarında hernangi bir çağırım belirtilmemiş ise, bu fonksiyon cdecl olarak çağırılacaktır. Yani aşağıdaki fonksiyonlar aynı şeyi ifade edip her iksinin de çevirimi aşağıda gösterilmektedir.</p><pre class="brush: c++">void bir_proc();
__cdecl void ikinici_proc();</pre><pre class="brush: delphi">procedure bir_proc; cdecl;
procedure ikinci_proc; cdecl;</pre><p>İleride makroları göreceğiz. Aşağıdaki makro tanımlamaları da geçerlidir ve kullanılmaktadır.</p><p>__stdcall = _stdcal = CALLBACK = WINAPI = APIENTRY = PASCAL = APIPRIVATE</p><p>__cdecl = _cdecl = WINAPIV</p><p>__fastcall = _fastcall</p><p>Yukarıda eşitliklik ile ifade edilenleri birbirlerinin aynısı olarak kabul edebilirsiniz.</p><h2>DLL Kullanımı ve Çağırımlar</h2><p
style="text-align: justify;">Normalde bir DLL&#8217;den bir fonksiyonu kullanmak için fonksiyonu nasıl tanımlayacağımızı bir hatırlayalım:</p><pre>
<pre class="brush: delphi">
const
  DLLDosyasi = &#039;birkutuphane.dll&#039;;
procedure bir_proc(); cdecl; external DLLDosyasi;
</pre></pre><p
style="text-align: justify;">Kendi DLL&#8217;imizi kullandığımızda fonksiyonu nasıl tanımlayacağımızı biliyoruz. Peki DLL&#8217;i biz yazmamış isek ne yapacağız?</p><p
style="text-align: justify;">Bu durumda, eğer herkes tarafından kullanılabilir bir DLL dosyası ise, DLL sağlayan firma, ekip, yazılımcı, vs. DLL dosyası ile beraber bir &#8220;header&#8221; dosyası sağlayacaktır.</p><p
style="text-align: justify;">Delphi&#8217;de, bildiğiniz gibi, unit iki bloktan oluşur. Birinci blok yani <strong>interface </strong>bloğu, unit tarafından &#8220;unit dışında&#8221; kullanılacak olan sınıf, değişken, fonksiyon, vs. &#8216;den oluşur. İkinci blok yani <strong>implementation </strong>bloğu ise, interface bloğunda tanımlanmış olan fonksiyon ve sınıfların esas kodlarından oluşur. Yani esas çalıştırılan kodlar implementation kısmında bulunur. Ayrıca implementation&#8217;da tanımlı herhangi bir değişken, fonksiyon, vs. eğer interface&#8217;de tanımlı değilse diğer unitlerde görünmezler ve kullanılamazlar.</p><p
style="text-align: justify;">C / C++ dosyaları da Delphi&#8217;nin unit dosya mantığının aynısıdır. Fakat Delphi&#8217;nin aksine C / C++ dosyaları tek parça halinde değil iki parça halinde tutulurlar. Delphi&#8217;de interface olarak ifade ettiğimiz blok C &#8216;de &#8220;header&#8221; olarak ifade edilir ve &#8220;.h&#8221; uzantısına sahiptir. Nadir de olsa C++&#8217;da header dosyaları &#8220;.hpp&#8221; uzantısı alabilirler. Delphi&#8217;de implementation olarak ifade edilen esas çalışan kodlar ise C&#8217;de &#8220;.c&#8221; ve C++&#8217;da ise &#8220;.cpp&#8221; uzantısı ile ifade edilen dosyalardadır.</p><p
style="text-align: justify;">Header dosyaları, şart olmasa da, genelde kütüphanenin &#8220;include&#8221; adlı klasöründe barındırılmaktadır. Kullanacağınız DLL&#8217;in header dosyası da bu veya bunun benzeri bir klasörde bulunacaktır. Header dosyası olmadan Delphi çevirimi yapmamız çok zor olacaktır. Hatta üst düzey assembler bilginiz olması gerekebilir. Bu yüzden DLL ile beraber en az bir adet header dosyasına sahip olduğunuzu varsayıyorum.</p><p
style="text-align: justify;">Bu başlık altında esas olarak anlatmak istediğim mevzuya şimdi geliyoruz.</p><p
style="text-align: justify;">DLL&#8217;e ait header dosyasına baktığımızda fonksiyonların hangi çağırım mekanizmalarını kullandıklarını görebiliyor ve anlayabiliyoruz. Fakat derlenmiş olan DLL dosyalarında bu çağırım mekanizmalarını belirten hernhangi bir işaret var mı?</p><p
style="text-align: justify;">Bunun için yardımcı bir araca ihtiyaç duyacağız. Aslında TDump isimli ve delphi ile beraber gelen bir konsol uygulaması bulunmakta. Ancak konsol uygulaması yerine göresel bir aracı tercih ederim. Ama illaki tdump kullanmak isteyen olursa &#8220;-b&#8221; parametresi ile beraber kullanabilirsiniz. Her neyse, ihtiyacımız olan program &#8220;<a
href="http://www.dependencywalker.com/" target="_blank">Dependency Walker</a>&#8221; . Bu program ile DLL&#8217;de bulunan tüm fonksiyonları isimleri ile beraber görebiliriz.</p><p
style="text-align: justify;">Peki header dosyasında fonksiyonlar ayrıntılı bir şekilde olmasına rağmen neden ekstra bir araca ihtiyaç duyuyoruz. Aslında ekstra bir programa ihtiyacımız yok. Header dosyaları fazlasıyla yeterlidir. Fakat bazen DLL&#8217;ler varsayılan ayarlarla derlenmemektedir. Bu da bize sorun çıkarabilmektedir.</p><p
style="text-align: justify;">DLL&#8217;ler derlenirken fonksiyon isimleri çeşitli ekler alırlar. Bu ekler, fonksiyonun hangi çağırımı kullandığını belirler. Ama bazen bu varsayılan isimlendirmenin dışına çıkan kütüphane yazılımcıları, bütün ekleri kaldırabiliyorlar. Mesela cdecl fonksiyonları önlerinde &#8220;_&#8221;  işaretini barındırırlar. Veya stdcall fonksiyonları fonksiyon isiminden sonra &#8220;@&#8221; işareti ve parametrelerin boyutlarını içeren bir dizi ekten ibarettirler. Dependency Walker gibi programlar, bize fonksiyonların hangi isimlerden oluştuğunu gösterecektir. Eğer header dosyasını Delphi&#8217;ye hatasız aktardık fakat halen fonksiyonun bulunmadığına dair hata alıyorsak demek ki isimlendirmeler yanlış demektir. Bunun için aşağıdaki yöntemi kullanmalıyız:</p><pre class="brush: delphi">procedure BirProc; cdecl; external DLLDosyasi name &#039;_bir_proc&#039;;</pre><p
style="text-align: justify;">Gördüğünüz gibi &#8220;external&#8221; direktifinin hemen sonuna bir boşluk ile beraber bir <strong>name </strong>direktifi ekledik. Bu &#8220;name&#8221; direktifi ile DLL&#8217;deki fonksiyona direk olarak işaret etmiş oluyoruz. Bu tekniği sadece ihtiyaç dahilinde kullanabilirsiniz. Veya C / C++ ismi size hoş gelmedi ise fonksiyonun ismini Delphi&#8217;de kullanım adını değiştirmek için kullanabilirsiniz.</p><p
style="text-align: justify;"><table
style="background-color: #e9eaeb; width: 100%;" border="0"><caption>Not</caption><tbody><tr><td
style="text-align: justify;">Bir tecrübemi aktarmak istiyorum. Eğer C / C++&#8217;a fazla hakim değilseniz, muhtemelen header dosyalarını çeviriken bir çok hata yapacaksınız. Bu durumda DLL&#8217;i statik olarak kullandığınızdan dolayı, delphi programı derleyecek ama çalıştıramayacktır. Ve program donacaktır. Çünkü istediği DLL içinde sizin tanımladığınız gibi bir fonksiyon bulamamıştır. Bunun yerine ilk başlarda, header dosyasının çevirimi doğru bir şekilde çevrilene kadar, DLL dosyasını dinamik olarak yükleyin. Bu şekilde çıkan hataları, hangi fonksiyon tanımlamasından kaynaklandığını belirleyebilirsiniz. Dinamik DLL yüklemesinin nasıl yapıldığını internetten araştırarak bulabilirsiniz.</td></tr></tbody></table><table
style="background-color: #e9eaeb; width: 100%;" border="0"><caption>Not</caption><tbody><tr><td
style="text-align: justify;">Header dosyalarını çevirmek için aslında JEDI kütüphanesine ait bir araç bulunmaktadır. Fakat bu araç da tam olarak header dosyalarını çevirememektedir. Daha doğrusu yine burada anlattığımız bilgilere ihtiyaç duyacaksınız. Bu araç sadece çok büyük dosyalarda yazım kolaylığı sağlamak açısından bir kolaylık getirmektedir. Ayrıca ileride anlatacğımız konular için bu araç yetersiz kalmaktadır. Bu araca Dr. Bob&#8217;un sitesinden ya da JEDI kütüphanesinden erişebilirsiniz. (Header Conversation Tool)</td></tr></tbody></table><p
style="text-align: justify;">Çağırım mekanizmalarına hakim olmak Delphi çevirimi noktasında size büyük kolaylık sağlayacaktır. Bu yüzden bu konuyu ilk sıraya aldım ve biraz da uzun tuttum.</p><h1>Veri Tipleri</h1><p
style="text-align: justify;">C / C++ kodları, çok fazla pointer ile ilgili işlemleri barındırmaktadır. Basit bir tip tanımlamasında bile pointerlara ihtiyaç duyarsınız. Fakat C / C++&#8217;da bulunan bu pointer kullanımı Delphi&#8217;ye geçtiğinde illaki pointer kalacak diye bir şart yoktur. Kullanımda bu olay farklılık göstermektedir.</p><p
style="text-align: justify;">İlk önce basit veri tiplerinden başlayalım. Aşağıdaki fonksiyona bir göz atalım:</p><pre class="brush: c++">char* birfonksiyon(void);</pre><p
style="text-align: justify;">Burada &#8220;char*&#8221; olarak çıktı veren bir fonksiyonuz mevcut. C&#8217;de &#8220;*&#8221; işareti pointer tanımlamak ve çarpım işlemlerini yapmak için kullanılır. Eğer char, int gibi bir tip ile birlikte kullanılıyorsa bu, pointer operatörüdür. Bu örnekte &#8220;char*&#8221; ifadesi bir char işaretçisini ifade eder. Bu Delphi&#8217;de PAnsiChar ile ifade edilir. PChar demiyorum çünkü Delphi 2009 ile beraber artık PChar unicode oldu. Fakat buradaki &#8220;char&#8221; ansi olan bir char tipidir. Bunun Delphi karşılığı:</p><pre class="brush: delphi">function birfonksiyon: PAnsiChar; cdecl;</pre><p
style="text-align: justify;">olacaktır. Burada kullanılan C / C++ pointer&#8217;ı aynı şekilde Delphi&#8217;de de pointer olarak geçmiştir. Fakat bazen C&#8217;de pointer&#8217;lar hem pointer tanımlamak için, hem dizi tanımlamak için hem de parametrelerde çıkış için kullanılabiliyor. Bunların ayırımını zamanla ve tecrübeyle kazanacaksınız. Aşağıda referans olarak kullanabileceğiniz bir tablo gözükmektedir. Bu tabloyu kullandıkça artık aşina olup tekrar dönüp bakmayacağınızı da zannediyorum. Ama şimdi her birine birer birer göz atmanızda yarar var.</p><table
border="1"><tbody><tr><th>C / C++ Tipi</th><th>Delphi Karşılığı</th><th>Delphi 2009 Alternatifi</th></tr><tr><td>char</td><td>AnsiChar</td><td></td></tr><tr><td>char*</td><td>PAnsiChar</td><td></td></tr><tr><td>wchar_t</td><td>WideChar</td><td>Char</td></tr><tr><td>wchar_t*</td><td>PWideChar</td><td>PChar</td></tr><tr><td>signed char</td><td>ShortInt</td><td></td></tr><tr><td>unsigned char</td><td>Byte</td><td></td></tr><tr><td>LPSTR veya PSTR</td><td>PAnsiChar</td><td></td></tr><tr><td>LPWSTR veya PWSTR</td><td>PWideChar</td><td>PChar</td></tr><tr><td>void*</td><td>Pointer</td><td></td></tr><tr><td>bool</td><td>Boolean</td><td></td></tr><tr><td>float</td><td>Single</td><td></td></tr><tr><td>double</td><td>Double</td><td></td></tr><tr><td>long double</td><td>Extended</td><td></td></tr><tr><td>int</td><td>Integer</td><td></td></tr><tr><td>signed int</td><td>Integer</td><td></td></tr><tr><td>unsigned int</td><td>Cardinal</td><td></td></tr><tr><td>UINT</td><td>Cardinal</td><td></td></tr><tr><td>unsigned long</td><td>Cardinal</td><td></td></tr><tr><td>unsigned long int</td><td>Cardinal</td><td></td></tr><tr><td>unsigned</td><td>Cardinal</td><td></td></tr><tr><td>long</td><td>LongInt</td><td></td></tr><tr><td>signed long</td><td>LongInt</td><td></td></tr><tr><td>long int</td><td>LongInt</td><td></td></tr><tr><td>DWORD</td><td>Cardinal veya DWORD</td><td></td></tr><tr><td>QWORD</td><td>QWORD</td><td></td></tr><tr><td>WORD</td><td>Word</td><td></td></tr><tr><td>unsigned short</td><td>Word</td><td></td></tr><tr><td>unsigned short int</td><td>Word</td><td></td></tr><tr><td>short</td><td>SmallInt</td><td></td></tr><tr><td>short int</td><td>SmallInt</td><td></td></tr><tr><td>signed short</td><td>SmallInt</td><td></td></tr></tbody></table><p
style="text-align: justify;">Tabloyu incelerseniz çoğu tipin birbirinin aynısı olduğunu anlarsınız. Bu yüzden tablo biraz uzunca oldu. Bunun nedeni C / C++&#8217;da bolca makro denilen yapıların kullanılmasıdır. Makrolar ile ilgili işlemleri ileride anlatacağımızdan şimdilik burada kısa kesiyoruz.</p><p
style="text-align: justify;">Gördüğünüz gibi string yerine PChar yada PAnsiChar kullanılmakta. Tabloda ayrıca Delphi 2009 ve yukarısında kullanılmak üzere verdiğim alternetifler de mevcut.</p><table
style="background-color: #e9eaeb; width: 100%;" border="0"><caption>Bir Tüyo</caption><tbody><tr><td
style="text-align: justify;">Tabi burada verilmeyen bir çok tip olabilir. Ama temel manada bunlar bize referans olacaktır. Diğer tipler için bir tüyomuz şöyle olacaktır. Mesela UINT gibi makro bir tipin ifade ettiği tipi,değeri bulabilmek için C++ Builder gibi herhangi bir derleyeci size kafi gelecektir. Tek yapmanız gereken aşağıdaki gibi bir yapıyı, derleyicinin kütüphane dosyalarında arattırıp bulmanızdır.<pre class="brush: c++">#define UINT unsigned int</pre><p
style="text-align: justify;">C++ Builder için, sadece Ctrl ile tipin üzerine tıklamınız kafidir. Yukarıdaki ifadede UINT makrosu, &#8220;unsigned int&#8221; olarak tanımlanmıştır. Geriye kalan sadece &#8220;unsigned int&#8221; için tablodan Delphi karşılığını öğrenmektir.</p></td></tr></tbody></table><p
style="text-align: justify;">Veri tipleri ile ilgili zamanı geldikçe yine değineceğiz. Ama giriş için bu kadarlık bilgi yeterli.</p><h1>Makrolar</h1><p
style="text-align: justify;">Diyeceksiniz ki, ne oluyor C dersine mi başladık? Eğer bir dilden diğer dile çevirim yapmak istiyorsanız her iki dilin de incelikleri bilmeniz gerekmektedir. Tabi biz burada bir C kitabı yazacak değiliz. Bunun yerine mümkün olduğunca kısa tutup püf noktalarını vermeye çalışıyorum. Fakat, yeri gelecek bir C kitabını karıştırmanız gerekebilecek veya C ile ilgili bir siteyi&#8230;</p><p
style="text-align: justify;">Makrolar C / C++ derleyicilerine, derlemeden hemen önce yapılacak olan işlemleri bildirir. Bir nevi Delphi&#8217;deki {$ ..} derleyici direktiflerine benzeselerde bunlar daha karmaşıklardır. Önemli nokta, makroların derlemeden hemen önce çalıştırılmasıdır ve derlemeye dahil olmamasıdır. Bu yüzden C / C++ derleyicileri precompile denilen bir işleme tabi tutulurlar. Bu da C / C++ derleyicilerinin neden bu kadar yavaş derlediklerinin bir sebebidir. Eğer C / C++ ile büyük bir programı derlememiş iseniz hala, Delphi gibi 1-2 sn içinde derlediğini zannedersiniz. Halbuki C/C++&#8217;da ömrünüz yarısı derlemekle geçer <img
src='http://www.diyezon.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p
style="text-align: justify;">Aşağıda tanımlı basit bir makro görüyorusunuz:</p><pre class="brush: c++">#define BIRMAKRO MakronunDegeri</pre><p
style="text-align: justify;">Makro burada gördüğünüz gibi #define ile tanımlanıyor. Delphide olduğu gibi #ifdef, #ifndef, #endif gibi ifadelerle bu makronun tanımlı olup olmadığı kontrol edilebilir.</p><p
style="text-align: justify;">Peki bu makro delphi&#8217;ye geçirilecek mi? Belki evet belki hayır. Eğer makro bir fonksiyonu tanımlıyorsa bu durumda makroyu delphide tanımlamalısınız. Aksi taktirde makronun değeri sizin için yeterlidir. Makroyu geçrimenize gerek yok.</p><p
style="text-align: justify;">Eğer önceki konudaki tüyoyu okudu iseniz makroların gerçek değerlerine nasıl ulaşacağımızı biliyoruz. Mesela aşağıdaki makroyu birebir delphi&#8217;ye geçirmeye luzum yoktur:</p><p>C:</p><pre>
<pre class="brush: c++">#define size_t unsigned int
__stdcall size_t getSize();</pre></pre><p>Delphi:</p><pre class="brush: delphi">function getSize: Cardinal; stdcall;</pre><p
style="text-align: justify;">Ama isterseniz size_t makrosunu bir tip olarak tanımlayabilirsiniz de:</p><pre class="brush: delphi">size_t = Cardinal;</pre><p
style="text-align: justify;">Ama lüzum yok. Peki hangi makroları delphi&#8217;ye çevirmemiz gerekli? Şimdiye kadarki tecrübeme göre genelde fonksiyon makrolarını geçrimek yeterli. Aşağıda örnek bir fonksyion makrosu mevcut ve devamında delphi kodlarını bulabilirsiniz:</p><pre class="brush: c++">#define Fonksiyon(Msg) MessageBox(NULL, Msg, NULL, NULL)</pre><pre>
<pre class="brush: delphi">procedure Fonksiyon(Msg: PChar); inline;
begin
  MessageBox(0, Msg, &#039;&#039;, 0);
end;</pre></pre><p
style="text-align: justify;">Gördüğünüz gibi sadece &#8220;<strong>inline</strong>;&#8221; olarak tanımlamamız aynı etkiyi yapacaktır. Çünkü &#8220;inline&#8221; direktifi de makro gibi fonksiyonun çağrıldığı yerde çalıştırılır. Inline ve makro fonksiyonlar için internette bir çok makale bulabilirsiniz.</p><p
style="text-align: justify;">Bunun dışında makrolar ile iligli olarak şunu söylemek istiyorum. Önceden de dediğim gibi her makronun bire bir Delphi&#8217;ye çevrilmesine gerek yoktur. Makro fonksiyonların haricinde bir de bazen makro sabitler de tanımlanabilir. Mesela:</p><pre>
<pre class="brush: c++">#define ei_NONE 0
#define ei_WRITE 1
#define ei_READ 2
#define ei_CREATE 3</pre></pre><p
style="text-align: justify;">Bu tanımlamaları ister const ile tek tek eşitleyerek yaparsınız isterseniz enumerator tanımlarsınız. Biz ikisini de görelim:</p><pre>
<pre class="brush: delphi">//const ile
const
  ei_NONE = 0;
  ei_WRITE = 1;
  ei_READ = 2;
  ei_CREATE = 3;
//enumerator ile
type
  Tei = (ei_NONE = 0, ei_WRITE = 1, ei_READ = 2, ei_CREATE = 3);</pre></pre><p>Tercih size kalmış&#8230;</p><p
style="text-align: justify;">Çok karmaşık makrolar geldiğinde internetten veya bir c kitabından yardım alabilirsiniz. Fakat bu kadarlık bilgi sizi fazlasıyla idare edecektir.</p><h1>Gelecek Makalede</h1><p
style="text-align: justify;">Daha yapacağımız çok işler olacak. Şimdilik bu verdiğimiz bilgiler ile kendiniz çevirimler deneyebilirsiniz. Fakat, daha görememiz gereken çok önemli konular mevcut. Özellikle fonksiyon parametreleri başlı başına bir konu başlığı.</p><p
style="text-align: justify;">Bununla beraber bu makale serisinde sadece DLL kullanımını görmeyeceğiz. Gelecek makalelerde DLL kullanmadan C obje dosyalarını direk olarak delphi&#8217;ye gömeceğiz. Böylece programınızın yanında ek bir DLL verme zorunluluğunuzda kalkacak. Tabi bu konu başlı başına bir makale bölümü olacaktır.</p><p
style="text-align: justify;">Yine gelecek makalelerde hedear dosyaları haricindeki, implementation olarak ifade ettiğimiz kısımları da sıfırdan Delphi&#8217;ye nasıl çevrileceğinden bahsedeceğiz. Daha doğrusu yine bazı püf noktalara değineceğiz. Yoksa tüm gramerin nasıl çevrileceğini anlatmak biraz uzun ve sıkıcı olabilir.</p><p
style="text-align: justify;">Bu bölümlük bu kadar.</p><p
style="text-align: justify;">Fikir, eleştiri ve önerilerinizi bekliyorum.</p><p
style="text-align: center;"><strong>Fatih Tolga Ata &#8211; 2009</strong></p> ]]></content:encoded> <wfw:commentRss>http://www.diyezon.com/c-den-delphiye-kod-cevirme-klavuzu-1/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using memcached
Page Caching using memcached
Database Caching 1/11 queries in 0.013 seconds using memcached
Object Caching 285/306 objects using memcached

Served from: www.diyezon.com @ 2012-02-08 12:21:41 -->
