Ported zmq bindings to LuaNativeObjects bindings generator.
parent
0c256e5815
commit
8a36da4e48
@ -0,0 +1,63 @@
|
||||
#
|
||||
# Lua bindings for 0MQ
|
||||
#
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(lua-zmq C)
|
||||
|
||||
set(BUILD_SHARED_LIBS TRUE)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||
|
||||
set(INSTALL_CMOD share/lua/cmod CACHE PATH "Directory to install Lua binary modules (configure lua via LUA_CPATH)")
|
||||
set(LUA_NATIVE_OBJECTS_PATH ../LuaNativeObjects CACHE PATH
|
||||
"Directory to LuaNativeObjects bindings generator.")
|
||||
set(USE_PRE_GENERATED_BINDINGS TRUE CACHE BOOL
|
||||
"Set this to FALSE to re-generate bindings using LuaNativeObjects")
|
||||
|
||||
set(COMMON_CFLAGS "${CFLAGS}")
|
||||
set(COMMON_LDFLAGS)
|
||||
set(COMMON_LIBS)
|
||||
|
||||
## Lua 5.1.x
|
||||
include(FindLua51)
|
||||
if(NOT ${LUA51_FOUND})
|
||||
message(FATAL_ERROR "The FindLua51 module could not find lua :-(")
|
||||
endif()
|
||||
set(COMMON_LIBS "${COMMON_LIBS};${LUA_LIBRARIES}")
|
||||
|
||||
## LibZMQ
|
||||
include(FindPkgConfig)
|
||||
pkg_search_module(ZMQ REQUIRED libzmq)
|
||||
set(COMMON_CFLAGS "${COMMON_CFLAGS} ${ZMQ_CFLAGS}")
|
||||
set(COMMON_LDFLAGS "${COMMON_LDFLAGS} ${ZMQ_LDFLAGS}")
|
||||
set(COMMON_LIBS "${COMMON_LIBS};${ZMQ_LIBRARIES}")
|
||||
|
||||
## LuaNativeObjects
|
||||
include(LuaNativeObjects)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${LUA_INCLUDE_DIR})
|
||||
|
||||
## LuaZMQ
|
||||
set(LUA_ZMQ_SRC
|
||||
zmq.nobj.lua
|
||||
)
|
||||
|
||||
if(${USE_PRE_GENERATED_BINDINGS})
|
||||
set(LUA_ZMQ_SRC pre_generated-zmq.nobj.c)
|
||||
else()
|
||||
# Generate Lua bindings.
|
||||
GenLuaNativeObjects(LUA_ZMQ_SRC)
|
||||
endif()
|
||||
|
||||
add_library(lua-zmq MODULE ${LUA_ZMQ_SRC})
|
||||
target_link_libraries(lua-zmq ${COMMON_LIBS})
|
||||
set_target_properties(lua-zmq PROPERTIES PREFIX "")
|
||||
set_target_properties(lua-zmq PROPERTIES COMPILE_FLAGS "${COMMON_CFLAGS}")
|
||||
set_target_properties(lua-zmq PROPERTIES OUTPUT_NAME zmq)
|
||||
|
||||
install(TARGETS lua-zmq
|
||||
DESTINATION "${INSTALL_CMOD}")
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
# Copyright (c) 2010 Aleksey Yeschenko <aleksey@yeschenko.com>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = `pkg-config lua5.1 --cflags` -fPIC -O3 -Wall
|
||||
LFLAGS = -shared `pkg-config --libs --cflags libzmq`
|
||||
INSTALL_PATH = `pkg-config lua5.1 --variable=INSTALL_CMOD`
|
||||
|
||||
|
||||
all: zmq.so
|
||||
|
||||
|
||||
zmq.lo: zmq.c
|
||||
$(CC) -o zmq.lo -c $(CFLAGS) zmq.c
|
||||
|
||||
|
||||
zmq.so: zmq.lo
|
||||
$(CC) -o zmq.so $(LFLAGS) zmq.lo
|
||||
|
||||
|
||||
install: zmq.so
|
||||
install -D -s zmq.so $(INSTALL_PATH)/zmq.so
|
||||
|
||||
|
||||
clean:
|
||||
rm -f zmq.so zmq.lo
|
||||
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Lua Native Objects
|
||||
#
|
||||
macro(GenLuaNativeObjects _src_files_var)
|
||||
set(_new_src_files)
|
||||
foreach(_src_file ${${_src_files_var}})
|
||||
if(_src_file MATCHES ".nobj.lua")
|
||||
string(REGEX REPLACE ".nobj.lua" ".nobj.c" _src_file_out ${_src_file})
|
||||
string(REGEX REPLACE ".nobj.lua" ".nobj.h" _header_file_out ${_src_file})
|
||||
add_custom_command(OUTPUT ${_src_file_out} ${_header_file_out}
|
||||
COMMAND lua ${LUA_NATIVE_OBJECTS_PATH}/native_objects.lua -outpath ${CMAKE_CURRENT_BINARY_DIR} -gen lua ${_src_file}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DEPENDS ${_src_file}
|
||||
)
|
||||
set_source_files_properties(${_src_file_out} PROPERTIES GENERATED TRUE)
|
||||
set_source_files_properties(${_header_file_out} PROPERTIES GENERATED TRUE)
|
||||
set(_new_src_files ${_new_src_files} ${_src_file_out})
|
||||
else(_src_file MATCHES ".nobj.lua")
|
||||
set(_new_src_files ${_new_src_files} ${_src_file})
|
||||
endif(_src_file MATCHES ".nobj.lua")
|
||||
endforeach(_src_file)
|
||||
set(${_src_files_var} ${_new_src_files})
|
||||
endmacro(GenLuaNativeObjects _src_files_var)
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
-- Copyright (c) 2010 by Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
object "ZMQ_Ctx" {
|
||||
c_source [[
|
||||
typedef void * ZMQ_Ctx;
|
||||
]],
|
||||
destructor "term" {
|
||||
c_call "ZMQ_Error" "zmq_term" {}
|
||||
},
|
||||
method "socket" {
|
||||
var_in{ "int", "type" },
|
||||
var_out{ "ZMQ_Socket", "sock", own = true },
|
||||
var_out{ "ZMQ_Error", "err"},
|
||||
c_source[[
|
||||
${sock} = zmq_socket(${this}, ${type});
|
||||
if(${sock} == NULL) ${err} = -1;
|
||||
]]
|
||||
},
|
||||
}
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
-- Copyright (c) 2010 by Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
-- Convert ZMQ Error codes into strings.
|
||||
error_code "ZMQ_Error" "int" {
|
||||
is_error_check = function(rec) return "(0 != ${" .. rec.name .. "})" end,
|
||||
default = "0",
|
||||
c_source [[
|
||||
if(err != 0) {
|
||||
err = zmq_errno();
|
||||
switch(err) {
|
||||
case EAGAIN:
|
||||
err_str = "timeout";
|
||||
break;
|
||||
case ETERM:
|
||||
err_str = "closed";
|
||||
break;
|
||||
default:
|
||||
err_str = zmq_strerror(err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
]],
|
||||
}
|
||||
|
||||
@ -0,0 +1,264 @@
|
||||
-- Copyright (c) 2010 by Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
object "ZMQ_Socket" {
|
||||
c_source [[
|
||||
/* detect zmq version >= 2.1.0 */
|
||||
#define VERSION_2_1 0
|
||||
#if defined(ZMQ_VERSION)
|
||||
#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION(2,1,0))
|
||||
#undef VERSION_2_1
|
||||
#define VERSION_2_1 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef void * ZMQ_Socket;
|
||||
|
||||
#if VERSION_2_1
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
typedef SOCKET socket_t;
|
||||
#else
|
||||
typedef int socket_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* socket option types. */
|
||||
#define OPT_TYPE_NONE 0
|
||||
#define OPT_TYPE_INT 1
|
||||
#define OPT_TYPE_UINT32 2
|
||||
#define OPT_TYPE_UINT64 3
|
||||
#define OPT_TYPE_INT64 4
|
||||
#define OPT_TYPE_STR 5
|
||||
#define OPT_TYPE_FD 6
|
||||
|
||||
static const int opt_types[] = {
|
||||
OPT_TYPE_NONE, /* unused */
|
||||
OPT_TYPE_UINT64, /* ZMQ_HWM */
|
||||
OPT_TYPE_INT64, /* ZMQ_SWAP */
|
||||
OPT_TYPE_UINT64, /* ZMQ_AFFINITY */
|
||||
OPT_TYPE_STR, /* ZMQ_IDENTITY */
|
||||
OPT_TYPE_STR, /* ZMQ_SUBSCRIBE */
|
||||
OPT_TYPE_STR, /* ZMQ_UNSUBSCRIBE */
|
||||
OPT_TYPE_INT64, /* ZMQ_RATE */
|
||||
OPT_TYPE_INT64, /* ZMQ_RECOVERY_IVL */
|
||||
OPT_TYPE_INT64, /* ZMQ_MCAST_LOOP */
|
||||
OPT_TYPE_UINT64, /* ZMQ_SNDBUF */
|
||||
OPT_TYPE_UINT64, /* ZMQ_RCVBUF */
|
||||
OPT_TYPE_INT64, /* ZMQ_RCVMORE */
|
||||
|
||||
#if VERSION_2_1
|
||||
OPT_TYPE_FD, /* ZMQ_FD */
|
||||
OPT_TYPE_UINT32, /* ZMQ_EVENTS */
|
||||
OPT_TYPE_INT, /* ZMQ_TYPE */
|
||||
OPT_TYPE_INT, /* ZMQ_LINGER */
|
||||
OPT_TYPE_INT, /* ZMQ_RECONNECT_IVL */
|
||||
OPT_TYPE_INT, /* ZMQ_BACKLOG */
|
||||
#endif
|
||||
};
|
||||
#define MAX_OPTS ZMQ_BACKLOG
|
||||
|
||||
]],
|
||||
|
||||
destructor "close" {
|
||||
c_call "ZMQ_Error" "zmq_close" {}
|
||||
},
|
||||
method "bind" {
|
||||
c_call "ZMQ_Error" "zmq_bind" { "const char *", "addr" }
|
||||
},
|
||||
method "connect" {
|
||||
c_call "ZMQ_Error" "zmq_connect" { "const char *", "addr" }
|
||||
},
|
||||
method "setopt" {
|
||||
var_in{ "uint32_t", "opt" },
|
||||
var_in{ "<any>", "val" },
|
||||
var_out{ "ZMQ_Error", "err" },
|
||||
c_source[[
|
||||
size_t val_len;
|
||||
const void *val;
|
||||
|
||||
socket_t fd_val;
|
||||
int int_val;
|
||||
uint32_t uint32_val;
|
||||
uint64_t uint64_val;
|
||||
int64_t int64_val;
|
||||
|
||||
if(${opt} > MAX_OPTS) {
|
||||
return luaL_argerror(L, ${opt::idx}, "Invalid socket option.");
|
||||
}
|
||||
|
||||
switch(opt_types[${opt}]) {
|
||||
case OPT_TYPE_FD:
|
||||
fd_val = luaL_checklong(L, ${val::idx});
|
||||
val = &fd_val;
|
||||
val_len = sizeof(fd_val);
|
||||
break;
|
||||
case OPT_TYPE_INT:
|
||||
int_val = luaL_checklong(L, ${val::idx});
|
||||
val = &int_val;
|
||||
val_len = sizeof(int_val);
|
||||
break;
|
||||
case OPT_TYPE_UINT32:
|
||||
uint32_val = luaL_checklong(L, ${val::idx});
|
||||
val = &uint32_val;
|
||||
val_len = sizeof(uint32_val);
|
||||
break;
|
||||
case OPT_TYPE_UINT64:
|
||||
uint64_val = luaL_checklong(L, ${val::idx});
|
||||
val = &uint64_val;
|
||||
val_len = sizeof(uint64_val);
|
||||
break;
|
||||
case OPT_TYPE_INT64:
|
||||
int64_val = luaL_checklong(L, ${val::idx});
|
||||
val = &int64_val;
|
||||
val_len = sizeof(int64_val);
|
||||
break;
|
||||
case OPT_TYPE_STR:
|
||||
val = luaL_checklstring(L, ${val::idx}, &(val_len));
|
||||
break;
|
||||
default:
|
||||
printf("Invalid socket option type, this shouldn't happen.\n");
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
${err} = zmq_setsockopt(${this}, ${opt}, val, val_len);
|
||||
]]
|
||||
},
|
||||
method "getopt" {
|
||||
var_in{ "uint32_t", "opt" },
|
||||
var_out{ "<any>", "val" },
|
||||
var_out{ "ZMQ_Error", "err" },
|
||||
c_source[[
|
||||
size_t val_len;
|
||||
|
||||
socket_t fd_val;
|
||||
int int_val;
|
||||
uint32_t uint32_val;
|
||||
uint64_t uint64_val;
|
||||
int64_t int64_val;
|
||||
#define STR_MAX 255
|
||||
char str_val[STR_MAX];
|
||||
|
||||
if(${opt} > MAX_OPTS) {
|
||||
lua_pushnil(L);
|
||||
lua_pushliteral(L, "Invalid socket option.");
|
||||
return 2;
|
||||
}
|
||||
|
||||
switch(opt_types[${opt}]) {
|
||||
case OPT_TYPE_FD:
|
||||
val_len = sizeof(fd_val);
|
||||
${err} = zmq_getsockopt(${this}, ${opt}, &fd_val, &val_len);
|
||||
if(0 == ${err}) {
|
||||
lua_pushinteger(L, (lua_Integer)fd_val);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case OPT_TYPE_INT:
|
||||
val_len = sizeof(int_val);
|
||||
${err} = zmq_getsockopt(${this}, ${opt}, &int_val, &val_len);
|
||||
if(0 == ${err}) {
|
||||
lua_pushinteger(L, (lua_Integer)int_val);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case OPT_TYPE_UINT32:
|
||||
val_len = sizeof(uint32_val);
|
||||
${err} = zmq_getsockopt(${this}, ${opt}, &uint32_val, &val_len);
|
||||
if(0 == ${err}) {
|
||||
lua_pushinteger(L, (lua_Integer)uint32_val);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case OPT_TYPE_UINT64:
|
||||
val_len = sizeof(uint64_val);
|
||||
${err} = zmq_getsockopt(${this}, ${opt}, &uint64_val, &val_len);
|
||||
if(0 == ${err}) {
|
||||
lua_pushinteger(L, (lua_Integer)uint64_val);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case OPT_TYPE_INT64:
|
||||
val_len = sizeof(int64_val);
|
||||
${err} = zmq_getsockopt(${this}, ${opt}, &int64_val, &val_len);
|
||||
if(0 == ${err}) {
|
||||
lua_pushinteger(L, (lua_Integer)int64_val);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case OPT_TYPE_STR:
|
||||
val_len = STR_MAX;
|
||||
${err} = zmq_getsockopt(${this}, ${opt}, str_val, &val_len);
|
||||
if(0 == ${err}) {
|
||||
lua_pushlstring(L, str_val, val_len);
|
||||
return 1;
|
||||
}
|
||||
#undef STR_MAX
|
||||
break;
|
||||
default:
|
||||
printf("Invalid socket option type, this shouldn't happen.\n");
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
lua_pushnil(L);
|
||||
]]
|
||||
},
|
||||
method "send" {
|
||||
var_in{ "const char *", "data" },
|
||||
var_in{ "int", "flags", is_optional = true },
|
||||
var_out{ "ZMQ_Error", "err" },
|
||||
c_source[[
|
||||
zmq_msg_t msg;
|
||||
/* initialize message */
|
||||
${err} = zmq_msg_init_size(&msg, ${data}_len);
|
||||
if(0 == ${err}) {
|
||||
/* fill message */
|
||||
memcpy(zmq_msg_data(&msg), ${data}, ${data}_len);
|
||||
/* send message */
|
||||
${err} = zmq_send(${this}, &msg, ${flags});
|
||||
/* close message */
|
||||
zmq_msg_close(&msg);
|
||||
}
|
||||
]]
|
||||
},
|
||||
method "recv" {
|
||||
var_in{ "int", "flags", is_optional = true },
|
||||
var_out{ "const char *", "data", has_length = true },
|
||||
var_out{ "ZMQ_Error", "err" },
|
||||
c_source[[
|
||||
zmq_msg_t msg;
|
||||
/* initialize message */
|
||||
${err} = zmq_msg_init(&msg);
|
||||
if(0 == ${err}) {
|
||||
/* receive message */
|
||||
${err} = zmq_recv(${this}, &msg, ${flags});
|
||||
if(0 == ${err}) {
|
||||
${data} = zmq_msg_data(&msg);
|
||||
${data}_len = zmq_msg_size(&msg);
|
||||
}
|
||||
}
|
||||
]],
|
||||
c_source "post" [[
|
||||
/* close message */
|
||||
zmq_msg_close(&msg);
|
||||
]]
|
||||
},
|
||||
}
|
||||
|
||||
@ -1,552 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Aleksey Yeschenko <aleksey@yeschenko.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define LUA_LIB
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#include <zmq.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* detect zmq version >= 2.1.0 */
|
||||
#define VERSION_2_1 0
|
||||
#if defined(ZMQ_VERSION)
|
||||
#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION(2,1,0))
|
||||
#undef VERSION_2_1
|
||||
#define VERSION_2_1 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MT_ZMQ_CONTEXT "MT_ZMQ_CONTEXT"
|
||||
#define MT_ZMQ_SOCKET "MT_ZMQ_SOCKET"
|
||||
|
||||
typedef struct {
|
||||
void *ptr;
|
||||
int should_free;
|
||||
} zmq_ptr;
|
||||
|
||||
static int Lzmq_version(lua_State *L)
|
||||
{
|
||||
int major, minor, patch;
|
||||
|
||||
zmq_version(&major, &minor, &patch);
|
||||
|
||||
lua_createtable(L, 3, 0);
|
||||
|
||||
lua_pushinteger(L, 1);
|
||||
lua_pushinteger(L, major);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushinteger(L, 2);
|
||||
lua_pushinteger(L, minor);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushinteger(L, 3);
|
||||
lua_pushinteger(L, patch);
|
||||
lua_settable(L, -3);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Lzmq_push_error(lua_State *L)
|
||||
{
|
||||
const char *error;
|
||||
lua_pushnil(L);
|
||||
switch(zmq_errno()) {
|
||||
case EAGAIN:
|
||||
lua_pushliteral(L, "timeout");
|
||||
break;
|
||||
case ETERM:
|
||||
lua_pushliteral(L, "closed");
|
||||
break;
|
||||
default:
|
||||
error = zmq_strerror(zmq_errno());
|
||||
lua_pushlstring(L, error, strlen(error));
|
||||
break;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int Lzmq_init(lua_State *L)
|
||||
{
|
||||
zmq_ptr *ctx = lua_newuserdata(L, sizeof(zmq_ptr));
|
||||
luaL_getmetatable(L, MT_ZMQ_CONTEXT);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
if (lua_islightuserdata(L, 1)) {
|
||||
// Treat a light userdata as a raw ZMQ context object, which
|
||||
// we'll silently wrap. (And we won't automatically call term
|
||||
// on it.)
|
||||
|
||||
ctx->ptr = lua_touserdata(L, 1);
|
||||
ctx->should_free = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int io_threads = luaL_checkint(L, 1);
|
||||
|
||||
ctx->ptr = zmq_init(io_threads);
|
||||
|
||||
if (!ctx->ptr) {
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
|
||||
// toboolean defaults to false, but we want a missing param #2
|
||||
// to mean true
|
||||
if (lua_isnil(L, 2)) {
|
||||
ctx->should_free = 1;
|
||||
} else {
|
||||
ctx->should_free = lua_toboolean(L, 2);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Lzmq_term(lua_State *L)
|
||||
{
|
||||
zmq_ptr *ctx = luaL_checkudata(L, 1, MT_ZMQ_CONTEXT);
|
||||
|
||||
if(ctx->ptr != NULL) {
|
||||
if(zmq_term(ctx->ptr) == 0) {
|
||||
ctx->ptr = NULL;
|
||||
} else {
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushboolean(L, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Lzmq_ctx_gc(lua_State *L)
|
||||
{
|
||||
zmq_ptr *ctx = luaL_checkudata(L, 1, MT_ZMQ_CONTEXT);
|
||||
if (ctx->should_free) {
|
||||
return Lzmq_term(L);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int Lzmq_ctx_lightuserdata(lua_State *L)
|
||||
{
|
||||
zmq_ptr *ctx = luaL_checkudata(L, 1, MT_ZMQ_CONTEXT);
|
||||
lua_pushlightuserdata(L, ctx->ptr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Lzmq_socket(lua_State *L)
|
||||
{
|
||||
zmq_ptr *ctx = luaL_checkudata(L, 1, MT_ZMQ_CONTEXT);
|
||||
int type = luaL_checkint(L, 2);
|
||||
|
||||
zmq_ptr *s = lua_newuserdata(L, sizeof(zmq_ptr));
|
||||
|
||||
s->ptr = zmq_socket(ctx->ptr, type);
|
||||
|
||||
if (!s->ptr) {
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
|
||||
luaL_getmetatable(L, MT_ZMQ_SOCKET);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Lzmq_close(lua_State *L)
|
||||
{
|
||||
zmq_ptr *s = luaL_checkudata(L, 1, MT_ZMQ_SOCKET);
|
||||
|
||||
if(s->ptr != NULL) {
|
||||
if(zmq_close(s->ptr) == 0) {
|
||||
s->ptr = NULL;
|
||||
} else {
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushboolean(L, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if VERSION_2_1
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
typedef SOCKET socket_t;
|
||||
#else
|
||||
typedef int socket_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int Lzmq_setsockopt(lua_State *L)
|
||||
{
|
||||
zmq_ptr *s = luaL_checkudata(L, 1, MT_ZMQ_SOCKET);
|
||||
int option = luaL_checkint(L, 2);
|
||||
|
||||
int rc = 0;
|
||||
|
||||
switch (option) {
|
||||
#if VERSION_2_1
|
||||
case ZMQ_FD:
|
||||
{
|
||||
socket_t optval = (socket_t) luaL_checklong(L, 3);
|
||||
rc = zmq_setsockopt(s->ptr, option, (void *) &optval, sizeof(socket_t));
|
||||
}
|
||||
break;
|
||||
case ZMQ_EVENTS:
|
||||
{
|
||||
int32_t optval = (int32_t) luaL_checklong(L, 3);
|
||||
rc = zmq_setsockopt(s->ptr, option, (void *) &optval, sizeof(int32_t));
|
||||
}
|
||||
break;
|
||||
case ZMQ_TYPE:
|
||||
case ZMQ_LINGER:
|
||||
case ZMQ_RECONNECT_IVL:
|
||||
case ZMQ_BACKLOG:
|
||||
{
|
||||
int optval = (int) luaL_checklong(L, 3);
|
||||
rc = zmq_setsockopt(s->ptr, option, (void *) &optval, sizeof(int));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case ZMQ_SWAP:
|
||||
case ZMQ_RATE:
|
||||
case ZMQ_RECOVERY_IVL:
|
||||
case ZMQ_MCAST_LOOP:
|
||||
{
|
||||
int64_t optval = (int64_t) luaL_checklong(L, 3);
|
||||
rc = zmq_setsockopt(s->ptr, option, (void *) &optval, sizeof(int64_t));
|
||||
}
|
||||
break;
|
||||
case ZMQ_IDENTITY:
|
||||
case ZMQ_SUBSCRIBE:
|
||||
case ZMQ_UNSUBSCRIBE:
|
||||
{
|
||||
size_t optvallen;
|
||||
const char *optval = luaL_checklstring(L, 3, &optvallen);
|
||||
rc = zmq_setsockopt(s->ptr, option, (void *) optval, optvallen);
|
||||
}
|
||||
break;
|
||||
case ZMQ_HWM:
|
||||
case ZMQ_AFFINITY:
|
||||
case ZMQ_SNDBUF:
|
||||
case ZMQ_RCVBUF:
|
||||
{
|
||||
uint64_t optval = (uint64_t) luaL_checklong(L, 3);
|
||||
rc = zmq_setsockopt(s->ptr, option, (void *) &optval, sizeof(uint64_t));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rc = -1;
|
||||
errno = EINVAL;
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
|
||||
lua_pushboolean(L, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Lzmq_getsockopt(lua_State *L)
|
||||
{
|
||||
zmq_ptr *s = luaL_checkudata(L, 1, MT_ZMQ_SOCKET);
|
||||
int option = luaL_checkint(L, 2);
|
||||
|
||||
size_t optvallen;
|
||||
|
||||
int rc = 0;
|
||||
|
||||
switch (option) {
|
||||
#if VERSION_2_1
|
||||
case ZMQ_FD:
|
||||
{
|
||||
socket_t optval;
|
||||
optvallen = sizeof(socket_t);
|
||||
rc = zmq_getsockopt(s->ptr, option, (void *) &optval, &optvallen);
|
||||
if (rc == 0) {
|
||||
lua_pushinteger(L, (lua_Integer) optval);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZMQ_EVENTS:
|
||||
{
|
||||
int32_t optval;
|
||||
optvallen = sizeof(int32_t);
|
||||
rc = zmq_getsockopt(s->ptr, option, (void *) &optval, &optvallen);
|
||||
if (rc == 0) {
|
||||
lua_pushinteger(L, (lua_Integer) optval);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZMQ_TYPE:
|
||||
case ZMQ_LINGER:
|
||||
case ZMQ_RECONNECT_IVL:
|
||||
case ZMQ_BACKLOG:
|
||||
{
|
||||
int optval;
|
||||
optvallen = sizeof(int);
|
||||
rc = zmq_getsockopt(s->ptr, option, (void *) &optval, &optvallen);
|
||||
if (rc == 0) {
|
||||
lua_pushinteger(L, (lua_Integer) optval);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case ZMQ_SWAP:
|
||||
case ZMQ_RATE:
|
||||
case ZMQ_RECOVERY_IVL:
|
||||
case ZMQ_MCAST_LOOP:
|
||||
case ZMQ_RCVMORE:
|
||||
{
|
||||
int64_t optval;
|
||||
optvallen = sizeof(int64_t);
|
||||
rc = zmq_getsockopt(s->ptr, option, (void *) &optval, &optvallen);
|
||||
if (rc == 0) {
|
||||
lua_pushinteger(L, (lua_Integer) optval);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZMQ_IDENTITY:
|
||||
{
|
||||
char id[256];
|
||||
memset((void *)id, '\0', 256);
|
||||
optvallen = 256;
|
||||
rc = zmq_getsockopt(s->ptr, option, (void *)id, &optvallen);
|
||||
id[255] = '\0';
|
||||
if (rc == 0) {
|
||||
lua_pushstring(L, id);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZMQ_HWM:
|
||||
case ZMQ_AFFINITY:
|
||||
case ZMQ_SNDBUF:
|
||||
case ZMQ_RCVBUF:
|
||||
{
|
||||
uint64_t optval;
|
||||
optvallen = sizeof(uint64_t);
|
||||
rc = zmq_getsockopt(s->ptr, option, (void *) &optval, &optvallen);
|
||||
if (rc == 0) {
|
||||
lua_pushinteger(L, (lua_Integer) optval);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rc = -1;
|
||||
errno = EINVAL;
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
|
||||
lua_pushboolean(L, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Lzmq_bind(lua_State *L)
|
||||
{
|
||||
zmq_ptr *s = luaL_checkudata(L, 1, MT_ZMQ_SOCKET);
|
||||
const char *addr = luaL_checkstring(L, 2);
|
||||
|
||||
if (zmq_bind(s->ptr, addr) != 0) {
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
|
||||
lua_pushboolean(L, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Lzmq_connect(lua_State *L)
|
||||
{
|
||||
zmq_ptr *s = luaL_checkudata(L, 1, MT_ZMQ_SOCKET);
|
||||
const char *addr = luaL_checkstring(L, 2);
|
||||
|
||||
if (zmq_connect(s->ptr, addr) != 0) {
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
|
||||
lua_pushboolean(L, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Lzmq_send(lua_State *L)
|
||||
{
|
||||
zmq_ptr *s = luaL_checkudata(L, 1, MT_ZMQ_SOCKET);
|
||||
size_t msg_size;
|
||||
const char *data = luaL_checklstring(L, 2, &msg_size);
|
||||
int flags = luaL_optint(L, 3, 0);
|
||||
|
||||
zmq_msg_t msg;
|
||||
if(zmq_msg_init_size(&msg, msg_size) != 0) {
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
memcpy(zmq_msg_data(&msg), data, msg_size);
|
||||
|
||||
int rc = zmq_send(s->ptr, &msg, flags);
|
||||
|
||||
if(zmq_msg_close(&msg) != 0) {
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
|
||||
lua_pushboolean(L, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Lzmq_recv(lua_State *L)
|
||||
{
|
||||
zmq_ptr *s = luaL_checkudata(L, 1, MT_ZMQ_SOCKET);
|
||||
int flags = luaL_optint(L, 2, 0);
|
||||
|
||||
zmq_msg_t msg;
|
||||
if(zmq_msg_init(&msg) != 0) {
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
|
||||
if(zmq_recv(s->ptr, &msg, flags) != 0) {
|
||||
// Best we can do in this case is try to close and hope for the best.
|
||||
zmq_msg_close(&msg);
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
|
||||
lua_pushlstring(L, zmq_msg_data(&msg), zmq_msg_size(&msg));
|
||||
|
||||
if(zmq_msg_close(&msg) != 0) {
|
||||
// Above string will be poped from the stack by the normalising code
|
||||
// upon sucessful return.
|
||||
return Lzmq_push_error(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_reg zmqlib[] = {
|
||||
{"version", Lzmq_version},
|
||||
{"init", Lzmq_init},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const luaL_reg ctxmethods[] = {
|
||||
{"__gc", Lzmq_ctx_gc},
|
||||
{"lightuserdata", Lzmq_ctx_lightuserdata},
|
||||
{"term", Lzmq_term},
|
||||
{"socket", Lzmq_socket},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const luaL_reg sockmethods[] = {
|
||||
{"__gc", Lzmq_close},
|
||||
{"close", Lzmq_close},
|
||||
{"setopt", Lzmq_setsockopt},
|
||||
{"getopt", Lzmq_getsockopt},
|
||||
{"bind", Lzmq_bind},
|
||||
{"connect", Lzmq_connect},
|
||||
{"send", Lzmq_send},
|
||||
{"recv", Lzmq_recv},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
#define set_zmq_const(s) lua_pushinteger(L,ZMQ_##s); lua_setfield(L, -2, #s);
|
||||
|
||||
LUALIB_API int luaopen_zmq(lua_State *L)
|
||||
{
|
||||
/* context metatable. */
|
||||
luaL_newmetatable(L, MT_ZMQ_CONTEXT);
|
||||
lua_createtable(L, 0, sizeof(ctxmethods) / sizeof(luaL_reg) - 1);
|
||||
luaL_register(L, NULL, ctxmethods);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
/* socket metatable. */
|
||||
luaL_newmetatable(L, MT_ZMQ_SOCKET);
|
||||
lua_createtable(L, 0, sizeof(sockmethods) / sizeof(luaL_reg) - 1);
|
||||
luaL_register(L, NULL, sockmethods);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
luaL_register(L, "zmq", zmqlib);
|
||||
|
||||
/* Socket types. */
|
||||
set_zmq_const(PAIR);
|
||||
set_zmq_const(PUB);
|
||||
set_zmq_const(SUB);
|
||||
set_zmq_const(REQ);
|
||||
set_zmq_const(REP);
|
||||
set_zmq_const(XREQ);
|
||||
set_zmq_const(XREP);
|
||||
set_zmq_const(PULL);
|
||||
set_zmq_const(PUSH);
|
||||
|
||||
/* Socket options. */
|
||||
set_zmq_const(HWM);
|
||||
set_zmq_const(SWAP);
|
||||
set_zmq_const(AFFINITY);
|
||||
set_zmq_const(IDENTITY);
|
||||
set_zmq_const(SUBSCRIBE);
|
||||
set_zmq_const(UNSUBSCRIBE);
|
||||
set_zmq_const(RATE);
|
||||
set_zmq_const(RECOVERY_IVL);
|
||||
set_zmq_const(MCAST_LOOP);
|
||||
set_zmq_const(SNDBUF);
|
||||
set_zmq_const(RCVBUF);
|
||||
set_zmq_const(RCVMORE);
|
||||
#if VERSION_2_1
|
||||
set_zmq_const(FD);
|
||||
set_zmq_const(EVENTS);
|
||||
set_zmq_const(TYPE);
|
||||
set_zmq_const(LINGER);
|
||||
set_zmq_const(RECONNECT_IVL);
|
||||
set_zmq_const(BACKLOG);
|
||||
|
||||
/* POLL events */
|
||||
set_zmq_const(POLLIN);
|
||||
set_zmq_const(POLLOUT);
|
||||
set_zmq_const(POLLERR);
|
||||
#endif
|
||||
|
||||
/* Send/recv options. */
|
||||
set_zmq_const(NOBLOCK);
|
||||
set_zmq_const(SNDMORE);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
|
||||
c_module "zmq" {
|
||||
-- module settings.
|
||||
use_globals = false,
|
||||
hide_meta_info = true,
|
||||
|
||||
include "zmq.h",
|
||||
|
||||
--
|
||||
-- Module constants
|
||||
--
|
||||
const "MAX_VSM_SIZE" { 30 },
|
||||
|
||||
-- message types
|
||||
const "DELIMITER" { 31 },
|
||||
const "VSM" { 32 },
|
||||
|
||||
-- message flags
|
||||
const "MSG_MORE" { 1 },
|
||||
const "MSG_SHARED" { 128 },
|
||||
|
||||
-- socket types
|
||||
const "PAIR" { 0 },
|
||||
const "PUB" { 1 },
|
||||
const "SUB" { 2 },
|
||||
const "REQ" { 3 },
|
||||
const "REP" { 4 },
|
||||
const "XREQ" { 5 },
|
||||
const "XREP" { 6 },
|
||||
const "PULL" { 7 },
|
||||
const "PUSH" { 8 },
|
||||
|
||||
-- socket options
|
||||
const "HWM" { 1 },
|
||||
const "SWAP" { 3 },
|
||||
const "AFFINITY" { 4 },
|
||||
const "IDENTITY" { 5 },
|
||||
const "SUBSCRIBE" { 6 },
|
||||
const "UNSUBSCRIBE" { 7 },
|
||||
const "RATE" { 8 },
|
||||
const "RECOVERY_IVL" { 9 },
|
||||
const "MCAST_LOOP" { 10 },
|
||||
const "SNDBUF" { 11 },
|
||||
const "RCVBUF" { 12 },
|
||||
const "RCVMORE" { 13 },
|
||||
const "FD" { 14 },
|
||||
const "EVENTS" { 15 },
|
||||
const "TYPE" { 16 },
|
||||
const "LINGER" { 17 },
|
||||
const "RECONNECT_IVL" { 18 },
|
||||
const "BACKLOG" { 19 },
|
||||
|
||||
-- send/recv flags
|
||||
const "NOBLOCK" { 1 },
|
||||
const "SNDMORE" { 2 },
|
||||
|
||||
-- poll events
|
||||
const "POLLIN" { 1 },
|
||||
const "POLLOUT" { 2 },
|
||||
const "POLLERR" { 4 },
|
||||
|
||||
-- devices
|
||||
const "STREAMER" { 1 },
|
||||
const "FORWARDER" { 2 },
|
||||
const "QUEUE" { 3 },
|
||||
|
||||
--
|
||||
-- Module static functions
|
||||
--
|
||||
c_function "version" {
|
||||
var_out{ "int", "major" },
|
||||
var_out{ "int", "minor" },
|
||||
var_out{ "int", "patch" },
|
||||
c_source[[
|
||||
zmq_version(&(${major}), &(${minor}), &(${patch}));
|
||||
]]
|
||||
},
|
||||
c_function "init" {
|
||||
var_in{ "int", "io_threads" },
|
||||
var_out{ "ZMQ_Ctx", "ctx", own = true },
|
||||
var_out{ "ZMQ_Error", "err"},
|
||||
c_source[[
|
||||
${ctx} = zmq_init(${io_threads});
|
||||
if(${ctx} == NULL) ${err} = -1;
|
||||
]]
|
||||
},
|
||||
|
||||
subfiles {
|
||||
"error.nobj.lua",
|
||||
"ctx.nobj.lua",
|
||||
"socket.nobj.lua",
|
||||
},
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue