2017-09-21 169 views
7

Haskell (GHC) 'de yazılan kod için bir geri arama işlevi sağlamak istiyorum. İşlevleri dışa/içe aktarmak ve çalışma zamanımda kodumla birlikte çalışmak için GCC C-derleyici benzeri işlev türlerini kullanır.extern "Statik geri çağırma fonksiyonu için" C "

Aslında daha metodunu sınıfına this işaretçi kabul eder ve çağrı bir geri arama işlevi sağlamak için vardır:

struct C 
{ 
    int f(int i) { ; } 
    static int f_callback(void * self, int i) 
    { 
     static_cast< C * >(self)->f(i); 
    } 
}; 

Mantıksal f_callback sınıf C bir parçasıdır, böylece karşılık gelen yerleştirdi ad alanı kapsamı.

Ama endişeleniyorum extern "C" dil belirtimini kullanmalıyım (çağrı geleneği burada önemlidir, ad mangling değil)? Düz ad alanında extern "C" işlevini bildirmek ve tanımlamak mümkündür, farklı ad alanlarında aynı adla tanımlanan extern "C" işlevleri için bir dizi özel kural vardır, ancak there is sınıf kapsamı ve basit ad alanı bir ad alanı arasında bir ayrım yoktur.

static extern "C" işlevini sınıf kapsamına tanımlamak mümkün mü?

+0

Hayır, bu mümkün değil IIRC. Fakat C ve C++ 'nın farklı bir ABI veya yığın çerçeveleme kullanmasından endişe etmenize gerek yok. – user0042

+0

@ user0042 Statik __cdecl 'daha güvenli bir şey olmaz mıydı? – Orient

+0

Taşınabilir olmayan bir ek açıklama var, ancak bunu kullanabilirsiniz. – user0042

cevap

5

Harici geri arama, belirli bir sınıfa bağlı olmayan tasarım gereğidir.

Statik bir sınıf üyesi, kodunuzun içeriğine göre güzel olabilir, ancak gerçekliği yanlış yansıtır. Bu nedenle, bağımsız bir extern "C" işlevi olmasını tavsiye ederim. Bu, yanlış anlaşılmayı önler ve varsayımları vurgular (örneğin, kendiliğin bir C olduğu varsayılır ama gerçekte başka bir şey olabilir). F() genel ise, tüm bunlar çok temiz olacaktır. Özel olacak olsaydı, geri aramanızı bir arkadaşınıza yapmalısınız ve bu sıkı bağlantı tekrar vurgulanacaktır.

Sargı alternatifi, aynı sonuca ulaşmak için sadece gereksiz bir aracı arayacaktır.