Forum: Diğer Konular RSS
C++ ile Object Pascal İçin Kod Yazarken Merak Ettiklerim
İbrahim #1
Üye Eki 2015 tarihinden beri · 129 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: C++ ile Object Pascal İçin Kod Yazarken Merak Ettiklerim
Selamün Aleyküm;

Altta bağlantısını vermiş olduğum siteden yararlanarak Object Pascal'dan C++ kodu çağırmaya çalışıyorum. Lakin burada da görüldüğü üzere şu sualler aklıma takıldı:
Bağlantı Adresi: http://rvelthuis.de/articles/articles-cppobjs.html

1-) İlk örnekte görüldüğü gibi bir C++ sınıfı yazılmış (Console sınıfı) ve alt tarafta da bu sınıf özelliğini kaybederek extern "C" ile saf fonksiyonlar yazılmış. Acaba bu şekilde değil de C++ sınıfını yazıp başka bir dilde extern "C" kullanmadan direk bu sınıftan nesne üretip kullanabilir miyiz? Misal olarak:
/* Bu sınıf için extern "C" kullanmadan başka dilde bu sınıfı kullanabilir miyiz? */
class Console
{
public:
  int get_int(int n) { return n; }
  std::string get_str(const std::string& str) { return str; }
  static void write(const std::string& str) { std::cout << str << '\n'; }
};
 
/* --- Misal Delphi'de şu şekilde direk kullanabilir miyiz? : --- */
 
var
  cons : Console;
 
  i : Integer;
  s : String;
begin
  i := cons.get_int(777);
  s := cons.get_str('Hello World!');
  Console.write('--- String ---');
end;

2-) "Using COM-style interfaces" başlığı altında:
struct __declspec(uuid("{9BBDA1A4-21E7-4D11-8F1C-E2AD13D2779C}"))
    IConsole : public System::IInterface
Bu satırda uuid ile benzersiz bir id oluşturulmuş. Peki bu id'yi neye göre yazmışlar? Mesela ben 32 karakter sayısını bozmadan misal şöyle kafadan bir id oraya yazsam olur mu? : "{7V9NCC32-4629-GOO1-P2P1-B036LGA299ZX}". Eğer kafadan yazamıyorsak nasıl böyle bir değer elde edebiliriz?

3-) Yine 2. sualimle ilgili olarak bu id değeri tam olarak kod içinde ne işe yarıyor? Ayrıca bu kod nasıl çalışıyor?

4-) __cdecl, __stdcall ve __fastcall tam olarak ne oluyor? Bunları biraz araştırdım lakin neden bu şekilde ayrı ayrı anahtar sözcükler oluşturmuşlar ve niçin bunları kullanmamız gerekiyor, bunların yanıtını tam olarak bulamadım.

Teşekkürler!
Bu mesaj İbrahim tarafından değiştirildi; zaman: 2016-12-29, 05:52.
erdem (Moderatör) #2
Üye Tem 2009 tarihinden beri · 902 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
İbrahim:
1-) İlk örnekte görüldüğü gibi bir C++ sınıfı yazılmış (Console sınıfı) ve alt tarafta da bu sınıf özelliğini kaybederek extern "C" ile saf fonksiyonlar yazılmış. Acaba bu şekilde değil de C++ sınıfını yazıp başka bir dilde extern "C" kullanmadan direk bu sınıftan nesne üretip kullanabilir miyiz?

Burada anlatıldığına  göre bir C++ sınıfını kullanmak için ilkönce C ile sarıcı işlevler yazmak gerekiyormuş.

http://leonardorame.blogspot.com.tr/2011/02/working-with-c…

Ben de ufak bir örnek yazdım.

#include <cstring>
#include <iostream>
using namespace std;
 
class Dunya
{
public:
    Dunya();
    void merhabaDunya(char * ileti);
};
 
Dunya::Dunya()
{
}
 
void Dunya::merhabaDunya(char * ileti)
{
    const char * merhaba = "C++'den merhaba!";
    strcpy(ileti, merhaba);
}
 
extern "C"
{
    void dunyaNesnesiOlustur(void * & dunya)
    {
        dunya = new Dunya();
    }
 
    void merhabaDunya(void * dunya, char * ileti)
    {
        Dunya * benimDunyam = (Dunya *) dunya;
        benimDunyam->merhabaDunya(ileti);
    }
 
    void dunyaNesnesiniSil(void * dunya)
    {
        delete (Dunya *) dunya;
        dunya = NULL;
    }
}

Burada sınıfın işlevlerine void * gösterge kullanılarak erişiliyor.

void * genel bir göstergedir. Yani void * türü diğer göstergelere tür dönüşümü yapılmadan dönüştürülebilir.

Derlemek için

g++ -fPIC -shared dunya.cc -o dunya.so


nm programı ile kütüphane içeriğine bakabiliriz.

$ nm dunya.so

[...]
000007a0 t __do_global_dtors_aux
00001ee4 t __do_global_dtors_aux_fini_array_entry
00002028 d __dso_handle
00001edc t __frame_dummy_init_array_entry
         w __gmon_start__
         U __gxx_personality_v0@@CXXABI_1.3
00000835 t __x86.get_pc_thunk.bx
00002030 A _edata
00002038 A _end
00000998 T _fini
0000063c T _init
00002030 b completed.6874
00000710 t deregister_tm_clones
00000873 T dunyaNesnesiOlustur
000008f8 T dunyaNesnesiniSil
000007f0 t frame_dummy
000008ca T merhabaDunya
00000750 t register_tm_clones
         U strcpy@@GLIBC_2.0

4-) __cdecl, __stdcall ve __fastcall tam olarak ne oluyor? Bunları biraz araştırdım lakin neden bu şekilde ayrı ayrı anahtar sözcükler oluşturmuşlar ve niçin bunları kullanmamız gerekiyor, bunların yanıtını tam olarak bulamadım.

Bunlar MS'e özgü bir takım değişken adlandırma ve geçirme kuralları.

https://msdn.microsoft.com/tr-TR/library/984x0h58.aspx
acehreli (Moderatör) #3
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4412 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Her dil (ve her C++ derleyicisi) kendi calling convention'ını ve ABI'ını tanımlama serbestisine sahiptir. extern "C", bu dilleri ortada buluşturuyor. Onu destekleyen her dil diğerlerini çağırabiliyor. Dolayısıyla, bu durumda extern "C" kullanmak gerekiyor.

D'nin bu konudaki bir üstünlüğü, C++ kodlarını extern(C) gerektirmeden, extern(C++) ile çağırabilmesi.

COM konusunu hiç bilmiyorum ama D'nin özellikle COM arayüzlerini destekleyecek biçimde tasarlandığını biliyorum.

__cdecl, __stdcall ve __fastcall; işlevler çağrılırken parametrelerin nasıl geçirildiklerini, dönüş değerinin nasıl döndürüldüğünü, onlar için çağrı yığıtından (call stack) ayrılan yerin kimin tarafından geri verildiği vs. belirleyen farklı yöntemler. Örneğin, __cdecl C dilinin yaygınlaştırdığı yöntem.

Ali
İbrahim #4
Üye Eki 2015 tarihinden beri · 129 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlarınız için teşekkürler. Anlaşılan extern "C" ile C++ kodlarını sarmalayacağız. Peki mesela C++ ile kodlarken JNI ile Jvm oluşturduğumuzda,  başka bir dil tarafından da bu C++ kodunu çalıştırdığımızda  doğru bir şekilde çalışır mı?
acehreli (Moderatör) #5
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4412 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
O teknolojileri bilmiyorum ama eğer onlar da extern "C" kullanıyorlarsa, evet, onlar da yazdığımız bu işlevleri çağırabilirler.

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-06-24, 22:27:48 (UTC -07:00)