lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Scott Shumaker wrote:
> - Many of these functions are only designed to be called by LUA.
> Since they aren't referenced anywhere else in my code, they tend to
> get stripped out at link-time.  My current workaround is to reference
> them in another translation unit, which is annoying.

If you export them, then they don't get stripped.

> - The functions are only addressable with the exact same name in the
> ffi.C namespace.  This isn't always desirable.  For example, I wanted
> to use the built-in htonl, htons and friends.  However, they are
> actually defined as macros on my system.  This can be trivially fixed
> by writing a wrapper function.  However, I can't name the wrapped
> function 'htonl', or else I'll have conflicts with the macro.  So I
> named my functions htonl2, etc - which means I have to address them
> through FFI as 'htonl2'.  Often, I'd like to be able to tell FFI what
> name to refer to them, and which namespace to stick them in.

The FFI supports GCC's symbol renaming facility:

  uint32_t htonl(uint32_t) asm("htonl2");

Also, calling a C function for htonl seems excessive. Use this
instead:

  local bit = require("bit")
  local htonl = ffi.abi("le") and bit.bswap or bit.tobit

> - My functions don't work at all unless I set -Wl,--export-dynamic in
> my makefile - which isn't something I really want to do.

Umm, why? Shared libraries also export all of their visible
functions ...

> I have a suggestion that would solve all 3 of these problems.
> 
> What about adding a function to ffi that is something along the lines
> of luaL_register / lua_openlib?
> 
> static const struct ffi_reg netFuncs [] = {
>     {"htonl",htonl2},
>     {"ntohl",ntohl2},
>     {NULL, NULL}  /* sentinel */
>   };
> 
> ffi_register(L, "net", netFuncs);

You can already do that. Return a pointer to a struct of function
pointers from C to Lua and use the struct like a namespace:

ffi.cdef[[
struct mylib {
  int (*foo)(int);
  int (*bar)(int);
  // ...
};
struct mylib *getmylib(void);
]]

local mylib = ffi.C.getmylib()
print(mylib.foo(1))
print(mylib.bar(2))

--Mike