Bir fonksiyonun dışarıdan erişildiğini nasıl açıklayabilirim?


9

Bu C'ye özgü bir sorudur. Çeviri birimi sınırları içinde mümkün olan her şeyi .hdosyada yalnızca birkaç işlevi açığa çıkarmaya çalışıyorum . Yani, staticdosya düzeyindeki nesnelere bağlantı veriyorum .

Şimdi, birkaç fonksiyonun diğer modüller tarafından çağrılması gerekiyor, ancak doğrudan değil. Modül / dosya / çeviri birimim, bir işleve bir işaretçi ileterek diğer modüllere abone olur. Daha sonra, belirli bir olay üzerine, işaretçi bazı argümanlarla çağrılır.

Bu yüzden, bu işlevlerin belirsiz bir yerden çağrıldığını nasıl çok açık hale getireceğimizi merak ediyorum.

  • Onlar olmalı staticveya extern(ve bunları ortaya çıkarmak .h)?
  • İşlevlerin adına bazı ipuçları eklemeli miyim?
  • Yoksa "X tarafından çağrılan" bir yorum koymak yeterli mi?

1
Bu mükemmel bir soru. Benim çözümüm (hiç de çok mutlu değilim, bu yüzden sadece bir yorum yapıyorum) çok sayıda başlık dosyası, mantıklı bir şekilde adlandırılmış ve sahip olmalarını istediğim kapsamda gruplama işlevleri yapmak. Yaptığım AStar kütüphanesi için AStar.h, AStar_private.h, AStar_packagePrivate.h, vb ... var
Shivan Dragon

Yanıtlar:


2

Derleme birimi (dosya) perspektifinden bakıldığında, kendinizle ilgilenmeniz gereken tek şey, işlevin dışarıda kullanılabilir olup olmadığıdır. Kullanılabilir hale getirilmesi, çağrılması amaçlandığı anlamına gelir ve bu çağrıların gerçekleşeceği varsayımı altında çalışmalısınız. Fonksiyonun kendisiyle olan endişeniz giriş noktasında başlar. Kontrolün ilk etapta oraya nasıl ulaştığı sadece onu gerçekleştiren kod için önemlidir.

Bilinen her CI uygulamasındaki bağlantı sembolik olduğundan, bir işlevi çağıran her şey sembolüne başvurmalıdır:

foo();  /* Direct */

some_function_pointer_t funcs[] = { &foo, &bar, &baz };  /* Indirect */

Eğer yanlışlıkla bildirirseniz foo()olmak static, programınız yönlendirilmezsiniz. Bunu non- olarak staticbildirirseniz, çağrılmayan açık bir işleve sahipsiniz. Bir işlevin kullanılıp kullanılmayacağı ile ilgili sorular, nesne dosyalarınızın sembol tablolarını dökerek veya kaynaklarda arayarak çözülebilir.


1

Bu yüzden, bu işlevlerin belirsiz bir yerden çağrıldığını çok açık hale nasıl getireceğim.

"Belirsiz" tanımlayın.
Yöntemler Shivan Ejderha zaten önerdiği üzere, bu "arayüzleri", iyi tanımlanmış "arayüzleri" ortaya çıkartılıp gereken olan sizin .h dosyaları. Başka bir programa "sağ" başlık dosyası vermezseniz, yöntemi çağıramaz.

Statik mi yoksa harici mi olmalılar (ve onları .h'de açığa çıkarmalılar)?

static örnek verileri içeren herhangi bir sınıf [benzeri yapılara] sahip olmadığınız sürece Tamam olabilir .
externdemek sen aslında hiç bunu uygulamaya yoktur; bir uygulama, bağlama işlemi sırasında başka bir yerden "edinilir".

İşlevlerin adına bazı ipuçları eklemeli miyim?

Yoksa "X tarafından çağrılan" bir yorum koymak yeterli mi?

Kesinlikle hayır.

Bu gibi yorumlar, ne kadar iyi bir anlama sahip olursa olsun, bunları yazmayı bitirdiğiniz anda geçersizdir.


İlk noktanıza hitap eden fonksiyonlar aşağıdaki gibi çağrılır. Bileşenim harici bir .hdosya içeriyor . Oradan bir işlev çağırır ve ona modülün kendi işlevlerinden birine bir işaretçi verir. Daha sonra harici kod, o işaretçide ne varsa arar. Böylece benim fonksiyonum başlık dosyamı içermeyen biri tarafından çağrılıyor, onun yerine onu ekliyorum.
Vorac

1
İkinci noktaya ilişkin olarak, benim anlayışım gereği, dosya kapsamında tanımlanan nesne varsayılan olarak dış bağlantıya sahiptir; bu nedenle externanahtar kelime gereksizdir .
Vorac

0

Geri arama işlevleri modülünüzde tanımlanmışsa ve kullanıcı hiçbir zaman kendi işlevlerinden birini sağlamazsa, başlatma aşamasında bir yer tutucu kullanabileceğinizi düşünüyorum. Yer tutucu, tipik enumolarak daha sonra dahili olarak doğru staticfonksiyona çevrilen bir yer tutucudur .


0

Onları hala yapardım static(sadece kimseyle bağlantılı olması ve çağrılması amaçlanmamıştır) ve amaçlarını adlarında harici işlevlere sağlanan geri aramalar olarak işaretlerim.

static çünkü saklayabildiğim kadar saklayabildiğim kadar saklamaya çalışıyorum.

Bunları adlarıyla işaretleyin, çünkü a), yorumlar güncelliğini yitirir ve b), geri çağrının sağlandığı yerde, bu işlevin bu şekilde kullanılması amaçlandığı açıkça görülür: bu temelde kırmızı bir bayrak yapar adlandırma kuralına uymayan bir işlevin adresini alıyor olabilir.


0

Kapsam değiştiricileri, "yeterince yakın" dokümantasyon biçimi olarak değil, derleyici için bilgi olarak kullanılmalıdır. Kullanımı staticdeğil istediğini, bunun geçerli derleyici ile çalışabilir halde - özellikle izinlerin bir C derleyicisi geri arama dahil, modül dışarıdan işlevi kullanılmaz hale getirmek.

Elbette koda bir yorum eklemelisiniz, çünkü bunun kafa karıştırıcı bir durum olduğunu görebilirsiniz. Alışılmadık veya beklenmedik herhangi bir şey için uygun bir yorum gerekir. Ancak, diğer cevaplarda belirtildiği gibi, yorumlar okunmamış olabilir veya eski olabilir.

Bu nedenle, geriye kalan tek seçenek işlevin geri arama olduğunu belirtmek için adlandırmaktır. Çoğu örnekler Ben kullanılması gördük _callbackya _cbda bir ek olarak veya cb_önek olarak. Kodunuzda geri çağrılar olağandışı ise uzun formu, yaygın ise kısa formu kullanın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.