From 22a1fb64422ce44ca4c25def827c448a9981e6fd Mon Sep 17 00:00:00 2001 From: Cempl Date: Wed, 29 Dec 2021 23:28:47 +0200 Subject: [PATCH 1/4] rpclib as shared library --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 721b0931..0ed82a4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,16 @@ cmake_minimum_required(VERSION 3.5.1) -project(rpc VERSION 2.3.0) +project(xpx.rpc VERSION 2.3.0) set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") +set(CMAKE_POSITION_INDEPENDENT_CODE ON) include(policies) include(msvc_support) include(coverage) include(check_warning_flag) +add_definitions(-w) + # # Options # From d6089e104ccbdbdca6d01181c5b784dd07fa1b7f Mon Sep 17 00:00:00 2001 From: Cempl Date: Thu, 30 Dec 2021 09:57:49 +0200 Subject: [PATCH 2/4] minor changes --- doc/pages/versions.md | 2 +- include/rpc/version.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/pages/versions.md b/doc/pages/versions.md index b56c57bc..7fcf6355 100644 --- a/doc/pages/versions.md +++ b/doc/pages/versions.md @@ -1,4 +1,4 @@ -You are reading the documentation of 2.3.0. +You are reading the documentation of ... If, for some reason you need the documentation of older versions, you can download them from this page. * [1.0.0](/archive/rpclib_docs_1.0.0.zip) diff --git a/include/rpc/version.h b/include/rpc/version.h index 47e19e92..cb699a59 100644 --- a/include/rpc/version.h +++ b/include/rpc/version.h @@ -5,9 +5,9 @@ namespace rpc { -static constexpr unsigned VERSION_MAJOR = 2; -static constexpr unsigned VERSION_MINOR = 3; -static constexpr unsigned VERSION_PATCH = 0; +static constexpr unsigned VERSION_MAJOR = ; +static constexpr unsigned VERSION_MINOR = ; +static constexpr unsigned VERSION_PATCH = ; } /* rpc */ From 2464326a3f1755cd730938c5bcdab80aa66b70e8 Mon Sep 17 00:00:00 2001 From: Cempl Date: Thu, 30 Dec 2021 12:39:42 +0200 Subject: [PATCH 3/4] Fixed build errors --- CMakeLists.txt | 5 +---- include/rpc/client.h | 33 +++++++++++++++---------------- include/rpc/config.h | 10 ++++++++++ include/rpc/config.h.in | 10 ++++++++++ include/rpc/dispatcher.h | 10 +++++----- include/rpc/msgpack/v1/object.hpp | 3 ++- include/rpc/server.h | 26 ++++++++++++------------ lib/rpc/server.cc | 5 ++--- 8 files changed, 59 insertions(+), 43 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ed82a4f..82b6f62b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,15 +2,12 @@ cmake_minimum_required(VERSION 3.5.1) project(xpx.rpc VERSION 2.3.0) set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") -set(CMAKE_POSITION_INDEPENDENT_CODE ON) include(policies) include(msvc_support) include(coverage) include(check_warning_flag) -add_definitions(-w) - # # Options # @@ -93,7 +90,7 @@ set(DEP_SOURCES ${RPCLIB_DEPENDENCIES}/src/format.cc ${RPCLIB_DEPENDENCIES}/src/posix.cc) -add_library(${PROJECT_NAME} +add_library(${PROJECT_NAME} SHARED lib/rpc/dispatcher.cc lib/rpc/server.cc lib/rpc/client.cc diff --git a/include/rpc/client.h b/include/rpc/client.h index fcd16ebe..69f1ad72 100644 --- a/include/rpc/client.h +++ b/include/rpc/client.h @@ -32,17 +32,17 @@ class client { //! \param addr The address of the server to connect to. This might be an //! IP address or a host name, too. //! \param port The port on the server to connect to. - client(std::string const &addr, uint16_t port); + EXPORT client(std::string const &addr, uint16_t port); //! \cond DOXYGEN_SKIP - client(client const &) = delete; + EXPORT client(client const &) = delete; //! \endcond //! \brief Destructor. //! //! During destruction, the connection to the server is gracefully closed. //! This means that any outstanding reads and writes are completed first. - ~client(); + EXPORT ~client(); //! \brief Calls a function with the given name and arguments (if any). //! @@ -58,7 +58,7 @@ class client { //! //! \throws rpc::rpc_error if the server responds with an error. template - RPCLIB_MSGPACK::object_handle call(std::string const &func_name, Args... args); + EXPORT RPCLIB_MSGPACK::object_handle call(std::string const &func_name, Args... args); //! \brief Calls a function asynchronously with the given name and //! arguments. @@ -77,8 +77,7 @@ class client { //! \returns A std::future, possibly holding a future result //! (which is a RPCLIB_MSGPACK::object). template - std::future async_call(std::string const &func_name, - Args... args); + EXPORT std::future async_call(std::string const &func_name, Args... args); //! \brief Sends a notification with the given name and arguments (if any). //! @@ -93,7 +92,7 @@ class client { //! \note This function returns immediately (possibly before the //! notification is written to the socket). template - void send(std::string const &func_name, Args... args); + EXPORT void send(std::string const &func_name, Args... args); //! \brief Returns the timeout setting of this client in milliseconds. //! @@ -105,24 +104,24 @@ class client { //! the preferred timeout mechanism remains using std::future. //! //! The default value for timeout is 5000ms (5 seconds). - nonstd::optional get_timeout() const; + EXPORT nonstd::optional get_timeout() const; //! \brief Sets the timeout for synchronous calls. For more information, //! see get_timeout(). - void set_timeout(int64_t value); + EXPORT void set_timeout(int64_t value); //! \brief Clears the timeout for synchronous calls. For more information, //! see get_timeout(). - void clear_timeout(); + EXPORT void clear_timeout(); //! \brief Enum representing the connection states of the client. enum class connection_state { initial, connected, disconnected, reset }; //! \brief Returns the current connection state. - connection_state get_connection_state() const; + EXPORT connection_state get_connection_state() const; //! \brief Waits for the completion of all ongoing calls. - void wait_all_responses(); + EXPORT void wait_all_responses(); private: //! \brief Type of a promise holding a future response. @@ -130,13 +129,13 @@ class client { enum class request_type { call = 0, notification = 2 }; - void wait_conn(); - void post(std::shared_ptr buffer, int idx, + EXPORT void wait_conn(); + EXPORT void post(std::shared_ptr buffer, int idx, std::string const& func_name, std::shared_ptr p); - void post(RPCLIB_MSGPACK::sbuffer *buffer); - int get_next_call_idx(); - RPCLIB_NORETURN void throw_timeout(std::string const& func_name); + EXPORT void post(RPCLIB_MSGPACK::sbuffer *buffer); + EXPORT int get_next_call_idx(); + RPCLIB_NORETURN EXPORT void throw_timeout(std::string const& func_name); private: static constexpr double buffer_grow_factor = 1.8; diff --git a/include/rpc/config.h b/include/rpc/config.h index f0611e34..79606d0b 100644 --- a/include/rpc/config.h +++ b/include/rpc/config.h @@ -8,6 +8,16 @@ #include "rpc/compatibility.h" +#if defined(WIN32) || defined(WIN64) +#ifdef DLL_EXPORTS +#define EXPORT __declspec(dllexport) +#else +#define EXPORT __declspec(dllimport) +#endif +#else +#define EXPORT __attribute__ ((visibility ("default"))) +#endif + namespace rpc { diff --git a/include/rpc/config.h.in b/include/rpc/config.h.in index d0538d01..5c52661f 100644 --- a/include/rpc/config.h.in +++ b/include/rpc/config.h.in @@ -8,6 +8,16 @@ #include "rpc/compatibility.h" +#if defined(WIN32) || defined(WIN64) +#ifdef DLL_EXPORTS +#define EXPORT __declspec(dllexport) +#else +#define EXPORT __declspec(dllimport) +#endif +#else +#define EXPORT __attribute__ ((visibility ("default"))) +#endif + namespace rpc { diff --git a/include/rpc/dispatcher.h b/include/rpc/dispatcher.h index 8044d4cb..c4ae56f2 100644 --- a/include/rpc/dispatcher.h +++ b/include/rpc/dispatcher.h @@ -95,17 +95,17 @@ class dispatcher { private: //! \brief Checks the argument count and throws an exception if //! it is not the expected amount. - static void enforce_arg_count(std::string const &func, std::size_t found, - std::size_t expected); + EXPORT static void enforce_arg_count(std::string const &func, std::size_t found, + std::size_t expected); - void enforce_unique_name(std::string const &func); + EXPORT void enforce_unique_name(std::string const &func); //! \brief Dispatches a call (which will have a response). - detail::response dispatch_call(RPCLIB_MSGPACK::object const &msg, + EXPORT detail::response dispatch_call(RPCLIB_MSGPACK::object const &msg, bool suppress_exceptions = false); //! \brief Dispatches a notification (which will not have a response) - detail::response dispatch_notification(RPCLIB_MSGPACK::object const &msg, + EXPORT detail::response dispatch_notification(RPCLIB_MSGPACK::object const &msg, bool suppress_exceptions = false); template RPCLIB_MSGPACK::object pack(T &&arg); diff --git a/include/rpc/msgpack/v1/object.hpp b/include/rpc/msgpack/v1/object.hpp index a7220a5f..13108edc 100644 --- a/include/rpc/msgpack/v1/object.hpp +++ b/include/rpc/msgpack/v1/object.hpp @@ -652,8 +652,9 @@ inline object::object(const msgpack_object& o) inline void operator<< (clmdep_msgpack::object& o, const msgpack_object& v) { + auto buff = static_cast(v); // FIXME beter way? - std::memcpy(&o, &v, sizeof(v)); + std::memcpy(&o, &buff, sizeof(v)); } inline object::operator msgpack_object() const diff --git a/include/rpc/server.h b/include/rpc/server.h index 60c6b86a..444342ce 100644 --- a/include/rpc/server.h +++ b/include/rpc/server.h @@ -31,13 +31,13 @@ class server { //! specified port. //! //! \param port The port number to listen on. - explicit server(uint16_t port); + EXPORT explicit server(uint16_t port); //! \brief Move constructor. This is implemented by calling the //! move assignment operator. //! //! \param other The other instance to move from. - server(server&& other) noexcept; + EXPORT server(server&& other) noexcept; //! \brief Constructs a server that listens on the specified address on //! the specified port. @@ -45,18 +45,18 @@ class server { //! \param address The address to bind to. This only works if oee of your //! network adapaters control the given address. //! \param port The port number to listen on. - server(std::string const &address, uint16_t port); + EXPORT server(std::string const &address, uint16_t port); //! \brief Destructor. //! //! When the server is destroyed, all ongoin sessions are closed gracefully. - ~server(); + EXPORT ~server(); //! \brief Move assignment operator. //! //! \param other The other instance to move from. //! \return The result of the assignment. - server& operator=(server&& other); + EXPORT server& operator=(server&& other); //! \brief Starts the server loop. This is a blocking call. //! @@ -66,7 +66,7 @@ class server { //! of this call. This means that the handlers are executed on the thread //! that calls `run`. Reads and writes are initiated by this function //! internally as well. - void run(); + EXPORT void run(); //! \brief Starts the server loop on one or more threads. This is a //! non-blocking call. @@ -77,7 +77,7 @@ class server { //! of the threads. //! //! \param worker_threads The number of worker threads to start. - void async_run(std::size_t worker_threads = 1); + EXPORT void async_run(std::size_t worker_threads = 1); //! \brief Binds a functor to a name so it becomes callable via RPC. //! @@ -89,7 +89,7 @@ class server { //! \param name The name of the functor. //! \param func The functor to bind. //! \tparam F The type of the functor. - template void bind(std::string const &name, F func) { + template EXPORT void bind(std::string const &name, F func) { disp_->bind(name, func); } @@ -98,21 +98,21 @@ class server { //! the server will try to gather textual data and return it to //! the client as an error response. //! \note Setting this flag only affects subsequent connections. - void suppress_exceptions(bool suppress); + EXPORT void suppress_exceptions(bool suppress); //! \brief Stops the server. //! \note This should not be called from worker threads. - void stop(); + EXPORT void stop(); //! \brief Returns port //! \note The port - unsigned short port() const; + EXPORT unsigned short port() const; //! \brief Closes all sessions gracefully. - void close_sessions(); + EXPORT void close_sessions(); //! \brief Closes a specific session. - void close_session(std::shared_ptr const& s); + EXPORT void close_session(std::shared_ptr const& s); private: RPCLIB_DECLARE_PIMPL() diff --git a/lib/rpc/server.cc b/lib/rpc/server.cc index 1565b2b4..b3f0ef8d 100644 --- a/lib/rpc/server.cc +++ b/lib/rpc/server.cc @@ -55,9 +55,8 @@ struct server::impl { void start_accept() { acceptor_.async_accept(socket_, [this](std::error_code ec) { if (!ec) { - auto ep = socket_.remote_endpoint(); - LOG_INFO("Accepted connection from {}:{}", ep.address(), - ep.port()); + LOG_INFO("Accepted connection from {}:{}", socket_.remote_endpoint().address(), + socket_.remote_endpoint().port()); auto s = std::make_shared( parent_, &io_, std::move(socket_), parent_->disp_, suppress_exceptions_); From 1587746ee92b75699edb482c81407e2d66952910 Mon Sep 17 00:00:00 2001 From: Abdelrahman Ragab Date: Mon, 20 Jun 2022 20:52:41 +0800 Subject: [PATCH 4/4] finalized build fixes --- CMakeLists.txt | 7 ++++++- include/rpc/client.h | 38 +++++++++++++++++++++----------------- include/rpc/dispatcher.h | 14 +++++++++----- include/rpc/server.h | 32 ++++++++++++++++++-------------- 4 files changed, 54 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 82b6f62b..807503d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,10 @@ include(msvc_support) include(coverage) include(check_warning_flag) +if(WIN32) + add_definitions(-D _WIN32_WINNT=0x0601) +endif() + # # Options # @@ -59,6 +63,8 @@ set(CMAKE_CXX_STANDARD ${RPCLIB_CXX_STANDARD}) # if (WIN32) set(RPCLIB_OS_DEF "RPCLIB_WIN32") +elseif (WIN64) + set(RPCLIB_OS_DEF "RPCLIB_WIN64") elseif (LINUX) set(RPCLIB_OS_DEF "RPCLIB_LINUX") elseif (APPLE) @@ -261,4 +267,3 @@ if(NOT MSVC) # Don't install pkg-config files when building with MSVC configure_file(rpclib.pc.in "${CMAKE_CURRENT_BINARY_DIR}/rpclib.pc" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rpclib.pc" DESTINATION "${libdir}/pkgconfig") endif() - diff --git a/include/rpc/client.h b/include/rpc/client.h index 69f1ad72..0a2e6a3e 100644 --- a/include/rpc/client.h +++ b/include/rpc/client.h @@ -20,7 +20,11 @@ namespace rpc { //! functions. This class supports calling functions synchronously and //! asynchronously. When the client object is created, it initiates connecting //! to the given server asynchronically and disconnects when it is destroyed. +#if __MINGW32__ class client { +#else +class EXPORT client { +#endif public: //! \brief Constructs a client. //! @@ -32,17 +36,17 @@ class client { //! \param addr The address of the server to connect to. This might be an //! IP address or a host name, too. //! \param port The port on the server to connect to. - EXPORT client(std::string const &addr, uint16_t port); + client(std::string const &addr, uint16_t port); //! \cond DOXYGEN_SKIP - EXPORT client(client const &) = delete; + client(client const &) = delete; //! \endcond //! \brief Destructor. //! //! During destruction, the connection to the server is gracefully closed. //! This means that any outstanding reads and writes are completed first. - EXPORT ~client(); + ~client(); //! \brief Calls a function with the given name and arguments (if any). //! @@ -58,7 +62,7 @@ class client { //! //! \throws rpc::rpc_error if the server responds with an error. template - EXPORT RPCLIB_MSGPACK::object_handle call(std::string const &func_name, Args... args); + RPCLIB_MSGPACK::object_handle call(std::string const &func_name, Args... args); //! \brief Calls a function asynchronously with the given name and //! arguments. @@ -77,7 +81,7 @@ class client { //! \returns A std::future, possibly holding a future result //! (which is a RPCLIB_MSGPACK::object). template - EXPORT std::future async_call(std::string const &func_name, Args... args); + std::future async_call(std::string const &func_name, Args... args); //! \brief Sends a notification with the given name and arguments (if any). //! @@ -92,7 +96,7 @@ class client { //! \note This function returns immediately (possibly before the //! notification is written to the socket). template - EXPORT void send(std::string const &func_name, Args... args); + void send(std::string const &func_name, Args... args); //! \brief Returns the timeout setting of this client in milliseconds. //! @@ -104,24 +108,24 @@ class client { //! the preferred timeout mechanism remains using std::future. //! //! The default value for timeout is 5000ms (5 seconds). - EXPORT nonstd::optional get_timeout() const; + nonstd::optional get_timeout() const; //! \brief Sets the timeout for synchronous calls. For more information, //! see get_timeout(). - EXPORT void set_timeout(int64_t value); + void set_timeout(int64_t value); //! \brief Clears the timeout for synchronous calls. For more information, //! see get_timeout(). - EXPORT void clear_timeout(); + void clear_timeout(); //! \brief Enum representing the connection states of the client. enum class connection_state { initial, connected, disconnected, reset }; //! \brief Returns the current connection state. - EXPORT connection_state get_connection_state() const; + connection_state get_connection_state() const; //! \brief Waits for the completion of all ongoing calls. - EXPORT void wait_all_responses(); + void wait_all_responses(); private: //! \brief Type of a promise holding a future response. @@ -129,13 +133,13 @@ class client { enum class request_type { call = 0, notification = 2 }; - EXPORT void wait_conn(); - EXPORT void post(std::shared_ptr buffer, int idx, + void wait_conn(); + void post(std::shared_ptr buffer, int idx, std::string const& func_name, std::shared_ptr p); - EXPORT void post(RPCLIB_MSGPACK::sbuffer *buffer); - EXPORT int get_next_call_idx(); - RPCLIB_NORETURN EXPORT void throw_timeout(std::string const& func_name); + void post(RPCLIB_MSGPACK::sbuffer *buffer); + int get_next_call_idx(); + RPCLIB_NORETURN void throw_timeout(std::string const& func_name); private: static constexpr double buffer_grow_factor = 1.8; @@ -143,4 +147,4 @@ class client { }; } -#include "rpc/client.inl" +#include "rpc/client.inl" \ No newline at end of file diff --git a/include/rpc/dispatcher.h b/include/rpc/dispatcher.h index c4ae56f2..0189f1d4 100644 --- a/include/rpc/dispatcher.h +++ b/include/rpc/dispatcher.h @@ -25,7 +25,11 @@ namespace detail { //! \brief This class maintains a registry of functors associated with their //! names, and callable using a msgpack-rpc call pack. +#if __MINGW32__ class dispatcher { +#else +class EXPORT dispatcher { +#endif public: //! \brief Binds a functor to a name so it becomes callable via RPC. //! \param name The name of the functor. @@ -95,17 +99,17 @@ class dispatcher { private: //! \brief Checks the argument count and throws an exception if //! it is not the expected amount. - EXPORT static void enforce_arg_count(std::string const &func, std::size_t found, + static void enforce_arg_count(std::string const &func, std::size_t found, std::size_t expected); - EXPORT void enforce_unique_name(std::string const &func); + void enforce_unique_name(std::string const &func); //! \brief Dispatches a call (which will have a response). - EXPORT detail::response dispatch_call(RPCLIB_MSGPACK::object const &msg, + detail::response dispatch_call(RPCLIB_MSGPACK::object const &msg, bool suppress_exceptions = false); //! \brief Dispatches a notification (which will not have a response) - EXPORT detail::response dispatch_notification(RPCLIB_MSGPACK::object const &msg, + detail::response dispatch_notification(RPCLIB_MSGPACK::object const &msg, bool suppress_exceptions = false); template RPCLIB_MSGPACK::object pack(T &&arg); @@ -121,4 +125,4 @@ class dispatcher { #include "dispatcher.inl" -#endif /* end of include guard: DISPATCHER_H_CXIVZD5L */ +#endif /* end of include guard: DISPATCHER_H_CXIVZD5L */ \ No newline at end of file diff --git a/include/rpc/server.h b/include/rpc/server.h index 444342ce..4be9c46e 100644 --- a/include/rpc/server.h +++ b/include/rpc/server.h @@ -25,19 +25,23 @@ class server_session; //! to allow binding functions before that. Use the `run` or `async_run` //! functions to start listening on the port. //! This class is not copyable, but moveable. +#if __MINGW32__ class server { +#else +class EXPORT server { +#endif public: //! \brief Constructs a server that listens on the localhost on the //! specified port. //! //! \param port The port number to listen on. - EXPORT explicit server(uint16_t port); + explicit server(uint16_t port); //! \brief Move constructor. This is implemented by calling the //! move assignment operator. //! //! \param other The other instance to move from. - EXPORT server(server&& other) noexcept; + server(server&& other) noexcept; //! \brief Constructs a server that listens on the specified address on //! the specified port. @@ -45,18 +49,18 @@ class server { //! \param address The address to bind to. This only works if oee of your //! network adapaters control the given address. //! \param port The port number to listen on. - EXPORT server(std::string const &address, uint16_t port); + server(std::string const &address, uint16_t port); //! \brief Destructor. //! //! When the server is destroyed, all ongoin sessions are closed gracefully. - EXPORT ~server(); + ~server(); //! \brief Move assignment operator. //! //! \param other The other instance to move from. //! \return The result of the assignment. - EXPORT server& operator=(server&& other); + server& operator=(server&& other); //! \brief Starts the server loop. This is a blocking call. //! @@ -66,7 +70,7 @@ class server { //! of this call. This means that the handlers are executed on the thread //! that calls `run`. Reads and writes are initiated by this function //! internally as well. - EXPORT void run(); + void run(); //! \brief Starts the server loop on one or more threads. This is a //! non-blocking call. @@ -77,7 +81,7 @@ class server { //! of the threads. //! //! \param worker_threads The number of worker threads to start. - EXPORT void async_run(std::size_t worker_threads = 1); + void async_run(std::size_t worker_threads = 1); //! \brief Binds a functor to a name so it becomes callable via RPC. //! @@ -89,7 +93,7 @@ class server { //! \param name The name of the functor. //! \param func The functor to bind. //! \tparam F The type of the functor. - template EXPORT void bind(std::string const &name, F func) { + template void bind(std::string const &name, F func) { disp_->bind(name, func); } @@ -98,21 +102,21 @@ class server { //! the server will try to gather textual data and return it to //! the client as an error response. //! \note Setting this flag only affects subsequent connections. - EXPORT void suppress_exceptions(bool suppress); + void suppress_exceptions(bool suppress); //! \brief Stops the server. //! \note This should not be called from worker threads. - EXPORT void stop(); + void stop(); //! \brief Returns port //! \note The port - EXPORT unsigned short port() const; + unsigned short port() const; //! \brief Closes all sessions gracefully. - EXPORT void close_sessions(); + void close_sessions(); //! \brief Closes a specific session. - EXPORT void close_session(std::shared_ptr const& s); + void close_session(std::shared_ptr const& s); private: RPCLIB_DECLARE_PIMPL() @@ -121,4 +125,4 @@ class server { } /* rpc */ -#endif /* end of include guard: SERVER_H_S0HB5KXY */ +#endif /* end of include guard: SERVER_H_S0HB5KXY */ \ No newline at end of file