I'm currently using LuaJIT and its FFI interface to call C functions from LUA scripts. What FFI does is to look at dynamic libraries' exported symbols and let the developer use it directly form LUA. Kind of like Python ctypes.

Obviously using dynamic libraries is not permitted in iOS for security reasons. So in order to come up with a solution I found the following snippet.

(c) 2012 +++ Filip Stoklas, aka FipS, http://www.4FipS.com +++
ARTICLE URL: http://forums.4fips.com/viewtopic.php?f=3&t=589

extern "C" {

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

} // extern "C"

#include <cassert>

// Please note that despite the fact that we build this code as a regular
// executable (exe), we still use __declspec(dllexport) to export
// symbols. Without doing that FFI wouldn't be able to locate them!

extern "C" __declspec(dllexport) void __cdecl hello_from_lua(const char *msg)
    printf("A message from LUA: %s\n", msg);

const char *lua_code =
"local ffi = require('ffi')                   \n"
"ffi.cdef[[                                   \n"
"const char * hello_from_lua(const char *);   \n" // matches the C prototype
"]]                                           \n"
"ffi.C.hello_from_lua('Hello from LUA!')      \n" // do actual C call

int main()
    lua_State *lua = luaL_newstate();

    const int status = luaL_dostring(lua, lua_code);
        printf("Couldn't execute LUA code: %s\n", lua_tostring(lua, -1));

    return 0;

// output:
// A message from LUA: Hello from LUA!

Basically, instead of using a dynamic library, the symbols are exported directly inside the executable file.

The question is: is this permitted by Apple?


  • \$\begingroup\$ It's Lua, not LUA. It's a proper name, not an acronym. \$\endgroup\$ Sep 25, 2012 at 21:32

2 Answers 2


Yes. I have declared functions in iOS code. I do not use these functions. I just forgot to remove them. They were used for debugging the code on other platform.

Such declaration is similar to putting functions in array if you have all your code loaded statically.

typedef int32 (*Func1) (void* userData);
Func1 funcs[] = {func1, func2, func3, NULL};

I have a set of apps with LUA. I use LUA to describe levels and debug.

You may submit a test app with such functionality to be reviewed by Apple. You can also make app to be not available for sale after review.

  • \$\begingroup\$ Just to make sure are there any runtime loading going on in your code? in above snippet, AFAIK luajit library dynamically loads the function at runtime -though it doesn't use a dynamic library to do that- \$\endgroup\$
    – tapirath
    Sep 25, 2012 at 11:11
  • \$\begingroup\$ No. I do not load. I just have EXPORT declaration by mistake from project I made on Windows with game engine that do not support iOS. Then I ported game with Marmalade that supports iOS. And submitted app to AppStore. Few export lines were left untouched. Apple can easy see export declaration. Nothing can link that code. Your main app's code will call your main app's code. BTW LuaJIT on iOS compiles as interpreter. It does not have compiler when compiled for iOS. May be that module will not work at all. \$\endgroup\$
    – Max
    Sep 25, 2012 at 11:27
  • \$\begingroup\$ Turns out FFI works with JIT turned off -albeit slow- I will follow your advice and try to send a test application for review \$\endgroup\$
    – tapirath
    Sep 25, 2012 at 12:03

Better you create static libraries, and even "static frameworks" (that is, like a classic framework is, a folder with the ".framework" extension and containing your Headers, resource files if any, and the lib itself, except that your lib must be a static library).

Apple doesn't want you doing this for App Store apps, but the operating system certainly allows it. Jailbreak apps use this technique all the time. You basically use a standard UNIX technique to dynamically open a library/framework, and then use stuff in it.

From iOSTechOverview

"If you want to integrate code from a framework or dynamic library into your application, you should link that code statically into your application’s executable file when building your project."

  • \$\begingroup\$ The problem is I want to keep using FFI which is not possible to use with static libraries. Also, with the approach in the snippet there is no dlopen() command issued. The functions are exported inside the executable and FFI uses those symbols instead of loading a library. Although the functions exported are still loaded at runtime there is no separate *.dylib file. It's all incorporated inside the exe. But is this allowed by Apple? \$\endgroup\$
    – tapirath
    Sep 25, 2012 at 9:48
  • \$\begingroup\$ @tapirath This is not allowed by Apple \$\endgroup\$ Sep 25, 2012 at 13:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .