C# ve Native

Native uygulamalar,  makine koduna dönüştürülmüş kodları içermektedir. Örneğin C/C++ ile geliştirilmiş bir programlar nativedir.

.Net tarafında native olarak yazılmış kütüphaneleri kullanabilmek için Windows’un apilerinden yararlanılmaktadır. Native metodların .net tarafında kullanmak için farklı yöntemler mevcut fakat burda anlatılacak olan sarmalama (wrapping) ile kullanımına dairdir.

Örnek olarak aşağıda C ile yazılmış toplama işlemi yapan bir kütüphanenin(.lib) C# tarafından kullanılmasına bakarsak;

Öncelikle kütüphaneyi oluşturuyoruz.

native1

Static library’i seçiyoruz. Burda Shared Library ya da Dynamic Link Library seçerseniz DLL üretebilirsiniz fakat anlatacığım yöntemde biz sarmalama (wrapping) yapacağımız için .lib seçiyoruz.

native2

Proje ismini ve diğer detayları belirliyoruz.

 native3

Yukardaki kod otomatik oluşturulmakta. Mâşallah bunu yazan arkadaş da çok dertliymiş 🙂

Süper metodumuzu zaten kendileri bizim için yazmış “SampleAddInt” adında. Geriye kalan metod ve yorum satırlarını temizliyoruz. Sarmala yapacağımız projede kullanılacak metodların bildirimlerini eklenen header (.h) dosyasında yapıyoruz.

ToplamaLib.h :

__cplusplus ve extern “C” ile link(bağlama) işlemini yapan C++ derleyicisine işlemini C’e göre yapmasını söylüyoruz. Çünkü metod C ile kodlandı.

TOPLAMALIB_H_INCLUDED kullanarak metod prototipin bir kere yazıldıktan sonra bir daha geçmemesi için kullanılıyor. Amacı başka bir yerden çağrıldıysa header dosyası derleme zamanı hata almamak için eklenir burda eklemesek de olur çünkü sadece tek bir .c dosyasında kullanılacak.

ToplamaLib.c :

#include ile başlık/header (.h) dosyasının dahil edilmesini sağlıyoruz ve SampleAddInt metodu tanımlaması yapılıyor.

Projeyi derliyoruz ve derlemenin sonuçlandırıldığı dizinde aşağıdakine benzer bir görünüm elde ediyoruz.

native7

“libToplamaLib.a” dosyasını “libToplamaLib.lib” olarak yeniden adlandırıyoruz. Çünkü Visual Studio .lib dosyası beklemektedir(Windows olduğu için). Derleyici lib dosyasını .a ile oluşturmuş olmasına rağmen .lib ile aynı özelliklere sahip olmakta. Bu uzantıda oluşmasının nedeni Code Blocks varsayılan derleyicisi GCC olduğu için .a olarak oluşturuyor.

Visual studio ile Class Library projesi oluşturuyoruz. Bu proje ile .lib uzantılı kütühanenin metodlarını çağırabilecek ve sarmalama yapabileceğiz.

native4

Projeye sağ tıklayarak “Properties” penceresine ulaşabilirsiniz. Burda aşağıdaki ayarları yaparak “ToplamaLib.h” dosyasını dahil edebilmeyi sağlıyoruz.

native5

 native6

Yukardaki işlemleri yaptıktan sonra #include önişlemci komutu kullanarak artık “ToplamaLib.h” header dosyasını dahil edebiliriz. (Yukardakileri yapmadan da tam yolu vererek yapılabilirdi)

native8

Projenin link aşamasında C ile yazılmış Static Library ‘i yani .lib dosyasını kullanabilmesi için aşağıdaki adımlar takip ediyoruz.

native11

native12

.lib dosyasının tam yolunu veriyoruz.

 

Wrapper’ın header dosyasında Sınıf adını yazıp, metodların bildirimlerini yapıyoruz.

Aşağıda Sınıf adı “Function” ve int dönen, 2 tane int parametre alan “AddInt” metodu bildirimi yapılmış.

native9

Bildirimi yapılan metodu “ToplamaLibWrapper.cpp” dosyasında C++ kodu ile tanımlamasını yapıyoruz. Bu tanımlamada C ile yazılan kütüphane fonksiyonun çağrıldığına dikkat edilmesi gerek. Bu sayede wrapping (sarmalama) işlemi gerçekleştiriliyor.

native10

Projeyi derliyoruz ve derlenen çıktının olduğu yerde .DLL oluşmuş olduğunu görmemiz gerekiyor.

native13

Artık bu DLL’i .Net uygulamalarına referans olarak ekleyerek kullanabiliriz.

Örnek olması maksadıyla bir Windows Form projesi açıyor ve düzenliyoruz.

native14

Üstün tasarım yetenekleriyle aşağıdakine benzer bir tasarım yapabilirsiniz  😀

native15

Kütüphaneyi kullanabilmek için projeye sağ tıklayıp “Add Reference” seçeneğiyle açılan pencereden oluşturduğumuz sarmalayıcı DLL’i ekliyoruz.

native16

DLL’i ekledikten sonra Topla butonuna DLL’deki metodu çağıracak kodu ekliyor ve uygulamayı test ediyoruz.

native17

 

Eğer “BadImageFormatException” , “…dosyasını veya derlemesini ya da bağımlılıklarından birini yükleyemedi. Geçersiz biçimdeki bir program yüklenmek istendi.” gibi aşağıdaki hatanın alınması durumunda (x64 sistemlere alınması daha muhtemel):

native18

Proje özelliklerine sağ tıklayarak Build sekmesi altından Target Platform x86 olarak değiştirildiğinde sorun olmamaktadır.

native19

UI projesinde platform değiştilmek istenmiyorsa Wrapper projesinde ayarlama yapılması gerekir.