Lua’s design is at least very clean and avoids allowing developers from accidentally creating nasty lifecycle design issues. It is very clear with Lua about ownership and visibility, which propagates cleanly through all aspects of Lua, such as working seamlessly with Lua’s garbage collection system. The design+code is also 100% portable to any processor/platform that has a C compiler (i.e. not requiring platform/arch specific #ifdefs, which is really useful when bringing up on a lesser-used platforms/chips.) And the design has very clear performance implications. In contrast, there was a recent talk at Google I/O about Android Dalvik vs. ARTs with respect to JNI bindings and performance. The results were non-obvious to say the least.
There is a research white paper that compared the C binding design tradeoffs of several different languages. http://www.inf.puc-rio.br/~roberto/docs/jucs-c-apis.pdf