2010-08-26 26 views
9

Ben dll (statik değil) olarak bağlı Lua kullanan küçük bir uygulama var. Ben kendi C++ - Yazılı dll'yi package.loadlib (libname, funcname) kullanarak Lua üzerinden yüklemek istiyorum. Bu amaçla Lua'nın lua_CFunction protokolünü izleyen bir işlevi vermem gerekiyor. Açıkçası bu nedenle projeme lua.h'u dahil etmeliyim ve Lua'nın fonksiyonlarını ve sonuçlarını geçmek için fonksiyonlarını kullanmalıyım. Bu yüzden benim sorularım:Lua tarafından bir C++ DLL yüklenebilir oluşturma

  1. DLL'üm, küçük bir uygulama sürecine zaten yüklenen Lua dll kullanacak mı?
  2. package.loadlib yüklüyse ve DLL'imi hemen yüklerim mi yoksa bir kez yüklendikten sonra DLL'im son lua scrpit yürütme veya uygulama sonlandırmasına kadar kalır mı?

cevap

8

özel sorularla başlayarak:

  1. Evet, ama sadece sizin DLL örtülü olarak kendisine bağlı olup olmadığını. Dikkatli olun, çünkü Lua VM'nin iki kopyasını yanlışlıkla uygulamanıza bağlarsanız, bu büyük bir karışıklığa neden olabilir. Bu nedenle, benzer sorunlar C çalışma zamanı için de geçerlidir. Tüm uygulamayı yalnızca Lua DLL dosyasının bir örneğine ve bir C çalışma süresine başvurduğunu doğrulamak için Dependency Walker altına yüklerim.

  2. Anladığım kadarıyla, package.loadlib() yalnızca adlandırılmış kitaplıktaki adlandırılmış işleve yüklenmekten ve bağlanmasından sorumludur. Döndürülmüş işlev nesnesi (adlandırılmış olduğunuz lua_CFunction temsil eden) olduğu sürece, DLL kesinlikle yüklenir. İşle ilgili son başvuruyu kaybederseniz, kütüphane çöp toplama için kullanılabilir ve eğer toplanırsa boşaltılacaktır. Lua-L posta listesinde, belirli bir DLL'nin kaldırılmasının nasıl sağlanacağına dair bir endişe var. Aksi takdirde, sadece içinde depolanan işleve erişebildiğiniz kadar DLL yüklenir varsayalım, iyi olacak.

beni bu üzerine inşa modül sistemi C veya C++ kodu ile Lua uzatmak için çok daha iyi bir yol olduğunu ekleyelim. Chapter 26 of Programming in Lua bunu daha ayrıntılı olarak açıklamaktadır ve bağlantı, ilk baskının çevrimiçi kopyasındaki (Lua 5.0'ı açıklayan) bu bölümdür. Modül sisteminin Lua 5.1'de ve yine Lua 5.2'de biraz değiştiğini unutmayın. PiL'nin ikinci veya üçüncü basımlarının bir kopyasının elde edilmesi (hem kitaplarda hem de e-kitap formlarında birçok kitapçıkta mevcuttur) yardımcı olabilir.

İşte bir yönetici özeti: C içinde foo adlı bir modül oluşturmak için, int luaopen_foo(lua_State *L) prototipini en az bir işlevle dışa aktaran foo.dll oluşturun. Bu fonksiyon, modülünüzü (tipik olarak, Lua 5.1'de luaL_register() veyaveya luaL_setfuncs() kullanarak, C işlevleri dolu bir tabloyu kaydetmek için) yükleyin ve bu tabloyu döndürmelidir. Lua tarafında, DLL'yi package.cpath'da açıklanan yol üzerinde bir yere koyun ve daha sonra local foo = require "foo" koduyla yüklenebilir. Çeşitli Lua 5.x sürümleri arasında başka ince farklar vardır, ancak bunların herhangi biri için derlenebilecek C kodu oluşturmak nispeten kolaydır.

Bu şekilde yapılması, modülün bir yoldan yüklenebilmesi, C veya Lua veya her ikisinin bir karışımında yazılması ve diğer modüller ile iyi bir şekilde oynamanın avantajına sahip olursunuz.Ayrıca, tek bir require çağrısı ile ihtiyaç duyduğunuz sayıda veya birkaç C işlevini de yükleyebilirsiniz.

+0

Mükemmel cevap için çok teşekkür ederim. Bana çok yardımcı oldu! Lua işlevselliği dışında DLL'm uygulamanın WndProc'una bağlanmasını ve özel araç çubuğumu ekleyebilmem için DLL'imin habersiz olduğum koşullar altında kaldırılmasını istemiyorum. –

+1

Sadece hazır olduğunuzda yayınladığınız kendi ek referansınızı tutarak, ömrü boyunca açık bir kontrol elde edebilirsiniz. 'LuaL_ref()' tablosunu 'LUA_REGISTRYINDEX' tablosunda C tarafındaki tutulabilen (tamsayı biçiminde) ve luaL_unref() 'ile serbest bırakılabilen herhangi bir nesneye referans olarak kullanabilirsiniz. – RBerteig

+0

Bu soruyu bulabilen herhangi biri için, Lua 5.2’de olduğu gibi, luaL_register’dan; 'luaL_newlib' kullanılmalıdır, çünkü dinamik olarak yüklenmiş modüller global ortamda herhangi bir şey kaydettirmemelidir. – bcrist

-1

Uygulamanızda olduğu gibi aynı Lua dll'ye dinamik olarak bağlanabilirsiniz.

package.loadlib'e gelince, bunun nasıl çalıştığını bilmiyorum. Kaynağı okuyor musun?