Wrapping an IntPtr in a Struct for safer Interop
I think, I would experiment with a safe or smart pointer approach in a way like this: 

public sealed class LuaHandle : IDisposable
{
  private static extern IntPtr lua_newstate();
  private static extern void lua_close(IntPtr state);

  private IntPtr m_handle = IntPtr.Zero;

  public LuaHandle()
  {
    m_handle = lua_newstate();
  }

  public IntPtr Handle =&gt; m_handle;


  public void Dispose()
  {
    if (m_handle != IntPtr.Zero)
    {
      lua_close(m_handle);
    }

    m_handle = IntPtr.Zero;
  }
}




Usage:

  using (LuaHandle luaHandle = new LuaHandle())
  {
    // do something with luaHandle.Handle
  }


In this way you - as a client of LuaHandle - don't have to deal with the extern api's at all and no invalid IntPtr can be past as argument to lua_close()