Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>There is a simple and direct answer, that may not be the most efficient answer. SWIG produces wrappers for manipulating objects from the scripting language side. For objects, it also synthesizes a wrapped constructor. So, the direct solution is to just let the Lua interpreter call SWIG's constructor to create the new object.</p> <p>For the wrapped <code>engine.GuiInst</code> class, you almost certainly can do something like:</p> <pre><code>int main() { lua_State *L=lua_open(); luaopen_engine(L); //this is swigs module int error=luaL_loadfile(L,"mainmenu.lua")|| lua_pcall(L, 0, 0, 0); luaL_dostring(L, "Init(engine.new_GuiInst())"); lua_close(L); } </code></pre> <p>For a one-shot case like script startup, the penalty of running a string constant through luaL_dostring() is not bad at all. I'd look harder to avoid it in an event callback or an inner loop, however.</p> <p>It does seem like there ought to be a way to convert a pointer directly into a wrapped object, I'm not spotting it in my own handful of SWIG generated wrappers.</p> <p><strong>Edit:</strong> Of course, the Lua fragment can be decomposed to API calls that get the engine table global on the stack, extract from it the <code>new_GuiInst</code> member, call it, then call the global <code>Init</code>, but the little bit of efficiency comes at the cost of some clarity.</p> <p>As for dealing with objects that shouldn't be constructed by accident in user code, as the clarified question indicates, my first impulse would be to let SWIG generate the constructor function, keep a private reference if needed later, and remove it from the table. Even a C module is (usually) just a table whose members contain function values. Being implemented in C doesn't make them read-only unless extra effort is taken.</p> <p>So, you could always retrieve the value of <code>engine.new_GuiInst</code> and park it in the registry (see <a href="http://www.lua.org/manual/5.1/manual.html#luaL_ref" rel="nofollow noreferrer"><code>luaL_ref()</code></a> and the discussion in <a href="http://www.lua.org/manual/5.1/manual.html#3.5" rel="nofollow noreferrer">section 3.5 of the Lua Reference Manual</a> of the pseudo-index <code>LUA_REGISTRYINDEX</code> for the details) for later use. Then, before letting any user code run, simply do the equivalent of <code>engine.new_GuiInst = nil</code>. I should note that for the C data types I've been playing with most recently, SWIG created two constructors for each type, named <code>new_TYPE</code> and <code>TYPE</code>. Both were visible in the module's table, and you would want to set both names to <code>nil</code>. If have much less experience with SWIG wrapping C++ classes, and the result may differ...</p> <p>You might want to check and review the whole content of the <code>engine</code> table returned by SWIG, and create a proxy object that contains only the methods you want available to your users. You can also change the <a href="http://www.lua.org/manual/5.1/manual.html#2.9" rel="nofollow noreferrer">environment</a> seen by the user script so that it only has the proxy available, and names the proxy <code>engine</code> as well. There has been a fair amount of discussion of <a href="http://lua-users.org/wiki/SandBoxes" rel="nofollow noreferrer">sandboxing</a> user scripts on the <a href="http://www.lua.org/lua-l.html" rel="nofollow noreferrer">Lua list</a> and at the <a href="http://lua-users.org/wiki/" rel="nofollow noreferrer">lua-users wiki</a>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload