On Wed, Sep 26, 2012 at 12:05:58PM +0200, Mike Pall wrote: > local ffi = require("ffi") > ffi.cdef[[ > struct whatever { > static const int FOO = 42; > static const int BAR = 99; > }; > ]] > local W = ffi.new("struct whatever") > print(W.FOO, W.BAR) > > Yes, these are compiled to actual constants, just like enum > constants (and unlike Lua table fields). Except that enum constants > are global in C, even if defined inside a struct. Note that it's > slightly more efficient to use an instance of the dummy struct (W) > as a namespace than using the ctype. Could one define non-integral constants more efficiently as well, without resorting to a Lua table on top of a C library namespace? In the MPICH2 implementation of MPI Version 2, there are dozens of constants that are cast to an opaque handle type: #define MPI_CHAR ((MPI_Datatype)0x4c000101) #define MPI_SHORT ((MPI_Datatype)0x4c000203) #define MPI_INT ((MPI_Datatype)0x4c000405) #define MPI_COMM_WORLD ((MPI_Comm)0x44000000) #define MPI_COMM_SELF ((MPI_Comm)0x44000001) Currently I generate a Lua table for these constants: ffi.cdef[[ typedef struct MPI_Comm *__ptr32 MPI_Comm; typedef struct MPI_Datatype *__ptr32 MPI_Datatype; ]] -- load MPI library into global namespace, too, -- to avoid a segmentation fault in MPI_Init local mpi = ffi.load("mpi", true) local defs = { MPI_CHAR = ffi.cast("MPI_Datatype", 0x4c000101), MPI_SHORT = ffi.cast("MPI_Datatype", 0x4c000203), MPI_INT = ffi.cast("MPI_Datatype", 0x4c000405), MPI_COMM_WORLD = ffi.cast("MPI_Comm", 0x44000000), MPI_COMM_SELF = ffi.cast("MPI_Comm", 0x44000001), } return setmetatable(defs, {__index = mpi}) The reason I would like to have the constants with correct type, rather than casting from an enum constant before a function call, is to allow consistent bindings for different implementations. In the OpenMPI implementation, the ABI uses global variables: extern struct ompi_predefined_communicator_t ompi_mpi_comm_world; extern struct ompi_predefined_communicator_t ompi_mpi_comm_self; #define MPI_COMM_WORLD ((MPI_Comm) ((void *) &(ompi_mpi_comm_world))) #define MPI_COMM_SELF ((MPI_Comm) ((void *) &(ompi_mpi_comm_self))) Which currently I translate to: ffi.cdef[[ typedef struct MPI_Comm *MPI_Comm; extern struct MPI_Comm MPI_COMM_WORLD asm("ompi_mpi_comm_world"); extern struct MPI_Comm MPI_COMM_SELF asm("ompi_mpi_comm_self"); ]] local mpi = ffi.load("mpi", true) local defs = { MPI_COMM_WORLD = ffi.cast("MPI_Comm", mpi.MPI_COMM_WORLD), MPI_COMM_SELF = ffi.cast("MPI_Comm", mpi.MPI_COMM_SELF), } return setmetatable(defs, {__index = mpi}) Is there a better way of binding the above with LuaJIT? Thanks, Peter