Genel API'sinin şuna benzeyen bir kitaplığı değerlendiriyorum:
libengine.h
/* Handle, used for all APIs */ typedef size_t enh; /* Create new engine instance; result returned in handle */ int en_open(int mode, enh *handle); /* Start an engine */ int en_start(enh handle); /* Add a new hook to the engine; hook handle returned in h2 */ int en_add_hook(enh handle, int hooknum, enh *h2);
Bunun enh
, birkaç farklı veri tipine ( motorlar ve kancalar ) bir tutamaç olarak kullanılan genel bir tutamaç olduğuna dikkat edin .
Dahili olarak, bu API'lerin çoğu elbette "tanıtıcıyı" yaptıkları bir iç yapıya dönüştürür malloc
:
engine.c
struct engine { // ... implementation details ... }; int en_open(int mode, *enh handle) { struct engine *en; en = malloc(sizeof(*en)); if (!en) return -1; // ...initialization... *handle = (enh)en; return 0; } int en_start(enh handle) { struct engine *en = (struct engine*)handle; return en->start(en); }
Şahsen, typedef
özellikle tip güvenliğini tehlikeye attığında, arkasındaki şeyleri saklamaktan nefret ediyorum . (Bir verilen enh
, aslında neyi kastettiğini nasıl bilebilirim?)
Bu nedenle, aşağıdaki API değişikliğini önererek bir çekme isteği gönderdim ( uyması için tüm kütüphaneyi değiştirdikten sonra ):
libengine.h
struct engine; /* Forward declaration */
typedef size_t hook_h; /* Still a handle, for other reasons */
/* Create new engine instance, result returned in en */
int en_open(int mode, struct engine **en);
/* Start an engine */
int en_start(struct engine *en);
/* Add a new hook to the engine; hook handle returned in hh */
int en_add_hook(struct engine *en, int hooknum, hook_h *hh);
Tabii ki, bu dahili API uygulamalarının çok daha iyi görünmesini sağlar, döküntüleri ortadan kaldırır ve tüketici güvenliğine göre / türünü güvenliğini korur.
libengine.c
struct engine
{
// ... implementation details ...
};
int en_open(int mode, struct engine **en)
{
struct engine *_e;
_e = malloc(sizeof(*_e));
if (!_e)
return -1;
// ...initialization...
*en = _e;
return 0;
}
int en_start(struct engine *en)
{
return en->start(en);
}
Bunu aşağıdaki nedenlerden dolayı tercih ediyorum:
- Eklenen tip güvenlik
- Tiplerin iyileştirilmiş netliği ve amaçları
- Kaldırılan atmalar ve
typedef
s - C'deki opak tipler için önerilen kalıbı izler.
Ancak, projenin sahibi çekme talebinde balyalandı (yeniden yazılmış):
Şahsen, açığa vurma fikrinden hoşlanmıyorum
struct engine
. Hala mevcut yolun daha temiz ve daha arkadaş canlısı olduğunu düşünüyorum.Başlangıçta, kanca tanıtıcısı için başka bir veri türü kullandım, ancak sonra kullanıma geçmeye karar verdim
enh
, böylece her türlü tutamaç basit tutmak için aynı veri türünü paylaşıyor. Bu kafa karıştırıcıysa, kesinlikle başka bir veri türü kullanabiliriz.Bakalım bu PR hakkında başkalarının ne düşündüğünü görelim.
Bu kütüphane şu anda özel bir beta aşamasındadır, bu nedenle endişelenecek çok fazla tüketici kodu yoktur (henüz). Ayrıca, isimleri biraz karıştırdım.
Bir opak tanıtıcısı, adlandırılmış bir opak yapıdan daha iyi nasıl olabilir?
Not: Bu soruyu kapatıldığı Kod İnceleme'de sordum .