hewei.it пре 5 година
родитељ
комит
5ec98bae66
56 измењених фајлова са 542 додато и 477 уклоњено
  1. 1 1
      CMakeLists.txt
  2. 1 1
      Makefile
  3. 2 1
      base/array.h
  4. 8 4
      base/hbase.c
  5. 29 31
      base/hbase.h
  6. 2 6
      base/hbuf.h
  7. 26 96
      base/hdef.h
  8. 0 2
      base/hdir.cpp
  9. 3 1
      base/hdir.h
  10. 2 3
      base/heap.h
  11. 3 1
      base/herr.h
  12. 29 30
      base/hfile.h
  13. 2 2
      base/hlog.c
  14. 21 19
      base/hlog.h
  15. 1 0
      base/hmath.h
  16. 3 2
      base/hmutex.h
  17. 0 15
      base/hplatform.h
  18. 0 1
      base/hproc.h
  19. 3 3
      base/hscope.h
  20. 2 0
      base/hsocket.c
  21. 14 14
      base/hsocket.h
  22. 13 12
      base/hstring.h
  23. 0 1
      base/hthread.h
  24. 17 17
      base/htime.h
  25. 4 2
      base/hurl.h
  26. 4 3
      base/hversion.h
  27. 0 4
      base/ifconfig.cpp
  28. 3 1
      base/ifconfig.h
  29. 10 2
      base/list.h
  30. 2 1
      base/queue.h
  31. 6 8
      base/ssl_ctx.h
  32. 5 3
      consul/consul.h
  33. 76 65
      event/hloop.h
  34. 7 3
      event/nlog.h
  35. 5 3
      event/nmap.h
  36. 1 2
      event/noevent.c
  37. 1 0
      examples/hloop_test.c
  38. 122 0
      hexport.h
  39. 4 3
      http/HttpMessage.h
  40. 2 1
      http/HttpParser.h
  41. 11 10
      http/client/http_client.h
  42. 7 6
      http/http_content.h
  43. 13 15
      http/httpdef.h
  44. 3 2
      http/server/HttpServer.h
  45. 2 1
      http/server/HttpService.h
  46. 1 0
      hv.h
  47. 2 0
      protocol/dns.c
  48. 14 17
      protocol/dns.h
  49. 13 15
      protocol/ftp.h
  50. 1 0
      protocol/icmp.c
  51. 3 7
      protocol/icmp.h
  52. 11 13
      protocol/smtp.h
  53. 6 8
      utils/base64.h
  54. 4 0
      utils/iniparser.cpp
  55. 10 10
      utils/iniparser.h
  56. 7 9
      utils/md5.h

+ 1 - 1
CMakeLists.txt

@@ -122,7 +122,7 @@ endif()
 # see Makefile
 set(ALL_SRCDIRS . base utils event protocol http http/client http/server consul examples)
 set(LIBHV_SRCDIRS . base utils event)
-set(LIBHV_HEADERS hv.h hconfig.h)
+set(LIBHV_HEADERS hv.h hconfig.h hexport.h)
 set(LIBHV_HEADERS ${LIBHV_HEADERS} ${BASE_HEADERS} ${UTILS_HEADERS} ${EVENT_HEADERS})
 
 if(WITH_PROTOCOL)

+ 1 - 1
Makefile

@@ -5,7 +5,7 @@ MAKEF=$(MAKE) -f Makefile.in
 ALL_SRCDIRS=. base utils event protocol http http/client http/server consul examples
 
 LIBHV_SRCDIRS = . base utils event
-LIBHV_HEADERS = hv.h hconfig.h
+LIBHV_HEADERS = hv.h hconfig.h hexport.h
 LIBHV_HEADERS += $(BASE_HEADERS) $(UTILS_HEADERS) $(EVENT_HEADERS)
 
 ifeq ($(WITH_PROTOCOL), yes)

+ 2 - 1
base/array.h

@@ -11,10 +11,11 @@
  */
 
 #include <assert.h> // for assert
+#include <stddef.h> // for NULL
 #include <stdlib.h> // for malloc,realloc,free
 #include <string.h> // for memset,memmove
 
-#include "hbase.h"
+#include "hbase.h"  // for HV_ALLOC, HV_FREE
 
 #define ARRAY_INIT_SIZE     16
 

+ 8 - 4
base/hbase.c

@@ -1,9 +1,5 @@
 #include "hbase.h"
 
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-
 #ifdef OS_DARWIN
 #include <mach-o/dyld.h> // for _NSGetExecutablePath
 #endif
@@ -56,6 +52,14 @@ void* safe_zalloc(size_t size) {
     return ptr;
 }
 
+void safe_free(void* ptr) {
+    if (ptr) {
+        free(ptr);
+        ptr = NULL;
+        ++g_free_cnt;
+    }
+}
+
 char* strupper(char* str) {
     char* p = str;
     while (*p != '\0') {

+ 29 - 31
base/hbase.h

@@ -1,7 +1,9 @@
 #ifndef HV_BASE_H_
 #define HV_BASE_H_
 
-#include "hdef.h"
+#include "hexport.h"
+#include "hplatform.h" // for bool
+#include "hdef.h" // for printd
 
 BEGIN_EXTERN_C
 
@@ -9,15 +11,15 @@ BEGIN_EXTERN_C
 extern unsigned int g_alloc_cnt;
 extern unsigned int g_free_cnt;
 
-void* safe_malloc(size_t size);
-void* safe_realloc(void* oldptr, size_t newsize, size_t oldsize);
-void* safe_calloc(size_t nmemb, size_t size);
-void* safe_zalloc(size_t size);
+HV_EXPORT void* safe_malloc(size_t size);
+HV_EXPORT void* safe_realloc(void* oldptr, size_t newsize, size_t oldsize);
+HV_EXPORT void* safe_calloc(size_t nmemb, size_t size);
+HV_EXPORT void* safe_zalloc(size_t size);
+HV_EXPORT void  safe_free(void* ptr);
 
 #define HV_ALLOC(ptr, size)\
     do {\
-        void** pptr = (void**)&(ptr);\
-        *pptr = safe_zalloc(size);\
+        *(void**)&(ptr) = safe_zalloc(size);\
         printd("alloc(%p, size=%llu)\tat [%s:%d:%s]\n", ptr, (unsigned long long)size, __FILE__, __LINE__, __FUNCTION__);\
     } while(0)
 
@@ -25,12 +27,8 @@ void* safe_zalloc(size_t size);
 
 #define HV_FREE(ptr)\
     do {\
-        if (ptr) {\
-            printd("free( %p )\tat [%s:%d:%s]\n", ptr, __FILE__, __LINE__, __FUNCTION__);\
-            free(ptr);\
-            ptr = NULL;\
-            ++g_free_cnt;\
-        }\
+        safe_free(ptr);\
+        printd("free( %p )\tat [%s:%d:%s]\n", ptr, __FILE__, __LINE__, __FUNCTION__);\
     } while(0)
 
 static inline void hv_memcheck() {
@@ -40,21 +38,21 @@ static inline void hv_memcheck() {
 #define HV_MEMCHECK    atexit(hv_memcheck);
 
 //--------------------safe string-------------------------------
-char* strupper(char* str);
-char* strlower(char* str);
-char* strreverse(char* str);
+HV_EXPORT char* strupper(char* str);
+HV_EXPORT char* strlower(char* str);
+HV_EXPORT char* strreverse(char* str);
 
-bool strstartswith(const char* str, const char* start);
-bool strendswith(const char* str, const char* end);
-bool strcontains(const char* str, const char* sub);
+HV_EXPORT bool strstartswith(const char* str, const char* start);
+HV_EXPORT bool strendswith(const char* str, const char* end);
+HV_EXPORT bool strcontains(const char* str, const char* sub);
 
 // strncpy n = sizeof(dest_buf)-1
 // safe_strncpy n = sizeof(dest_buf)
-char* safe_strncpy(char* dest, const char* src, size_t n);
+HV_EXPORT char* safe_strncpy(char* dest, const char* src, size_t n);
 
 // strncat n = sizeof(dest_buf)-1-strlen(dest)
 // safe_strncpy n = sizeof(dest_buf)
-char* safe_strncat(char* dest, const char* src, size_t n);
+HV_EXPORT char* safe_strncat(char* dest, const char* src, size_t n);
 
 #if !HAVE_STRLCPY
 #define strlcpy safe_strncpy
@@ -65,23 +63,23 @@ char* safe_strncat(char* dest, const char* src, size_t n);
 #endif
 
 #define strrchr_dot(str) strrchr(str, '.')
-char* strrchr_dir(const char* filepath);
+HV_EXPORT char* strrchr_dir(const char* filepath);
 
 // basename
-const char* hv_basename(const char* filepath);
-const char* hv_suffixname(const char* filename);
+HV_EXPORT const char* hv_basename(const char* filepath);
+HV_EXPORT const char* hv_suffixname(const char* filename);
 // mkdir -p
-int hv_mkdir_p(const char* dir);
+HV_EXPORT int hv_mkdir_p(const char* dir);
 // rmdir -p
-int hv_rmdir_p(const char* dir);
+HV_EXPORT int hv_rmdir_p(const char* dir);
 
 // 1 y on yes true enable
-bool getboolean(const char* str);
+HV_EXPORT bool getboolean(const char* str);
 
-char* get_executable_path(char* buf, int size);
-char* get_executable_dir(char* buf, int size);
-char* get_executable_file(char* buf, int size);
-char* get_run_dir(char* buf, int size);
+HV_EXPORT char* get_executable_path(char* buf, int size);
+HV_EXPORT char* get_executable_dir(char* buf, int size);
+HV_EXPORT char* get_executable_file(char* buf, int size);
+HV_EXPORT char* get_run_dir(char* buf, int size);
 
 END_EXTERN_C
 

+ 2 - 6
base/hbuf.h

@@ -1,12 +1,8 @@
 #ifndef HV_BUF_H_
 #define HV_BUF_H_
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "hdef.h"
-#include "hbase.h"
+#include "hdef.h"   // for MAX
+#include "hbase.h"  // for HV_ALLOC, HV_FREE
 
 typedef struct hbuf_s {
     char*  base;

+ 26 - 96
base/hdef.h

@@ -1,7 +1,10 @@
 #ifndef HV_DEF_H_
 #define HV_DEF_H_
 
-#include "hplatform.h"
+#include <stddef.h>
+#include <stdio.h>  // for printf, fprintf
+#include <stdlib.h> // for malloc, free
+#include <string.h> // for memset
 
 #ifndef ABS
 #define ABS(n)  ((n) > 0 ? (n) : -(n))
@@ -42,19 +45,6 @@
 #define FLOAT_PRECISION     1e-6
 #define FLOAT_EQUAL_ZERO(f) (ABS(f) < FLOAT_PRECISION)
 
-// @param[IN|OUT|INOUT]
-#ifndef IN
-#define IN
-#endif
-
-#ifndef OUT
-#define OUT
-#endif
-
-#ifndef INOUT
-#define INOUT
-#endif
-
 #ifndef INFINITE
 #define INFINITE    (uint32_t)-1
 #endif
@@ -132,7 +122,7 @@ ASCII:
 #define LLU(v)  ((unsigned long long)(v))
 #endif
 
-#ifndef OS_WIN
+#ifndef _WIN32
 
 // MAKEWORD, HIBYTE, LOBYTE
 #ifndef MAKEWORD
@@ -160,7 +150,7 @@ ASCII:
 #define LOWORD(n)        ( (WORD)(n & 0xffff) )
 #endif
 
-#endif // OS_WIN
+#endif // _WIN32
 
 // MAKEINT64, HIINT, LOINT
 #ifndef MAKEINT64
@@ -197,7 +187,11 @@ ASCII:
 #endif
 
 #ifndef NULL
-#define NULL        0
+#ifdef __cplusplus
+    #define NULL    0
+#else
+    #define NULL    ((void*)0)
+#endif
 #endif
 
 #ifndef TRUE
@@ -208,17 +202,17 @@ ASCII:
 #define FALSE       0
 #endif
 
-// @field[OPTIONAL|REQUIRED|REPEATED]
-#ifndef OPTIONAL
-#define OPTIONAL
-#endif
-
-#ifndef REQUIRED
-#define REQUIRED
-#endif
-
-#ifndef REPEATED
-#define REPEATED
+#ifndef SAFE_ALLOC
+#define SAFE_ALLOC(p, size)\
+    do {\
+        void* ptr = malloc(size);\
+        if (!ptr) {\
+            fprintf(stderr, "malloc failed!\n");\
+            exit(-1);\
+        }\
+        memset(ptr, 0, size);\
+        *(void**)&(p) = ptr;\
+    } while(0)
 #endif
 
 #ifndef SAFE_FREE
@@ -258,80 +252,16 @@ ASCII:
 ((type*)((char*)(ptr) - offsetof(type, member)))
 #endif
 
-#ifndef prefetch
-#ifdef __GNUC__
-#define prefetch(x) __builtin_prefetch(x)
-#else
-#define prefetch(x) (void)0
-#endif
-#endif
-
 #ifdef PRINT_DEBUG
-#define printd printf
+#define printd(...) printf(__VA_ARGS__)
 #else
 #define printd(...)
 #endif
 
-// __cplusplus
-#ifdef __cplusplus
-
-#ifndef EXTERN_C
-#define EXTERN_C            extern "C"
-#endif
-
-#ifndef BEGIN_EXTERN_C
-#define BEGIN_EXTERN_C      extern "C" {
-#endif
-
-#ifndef END_EXTERN_C
-#define END_EXTERN_C        } // extern "C"
-#endif
-
-#ifndef BEGIN_NAMESPACE
-#define BEGIN_NAMESPACE(ns) namespace ns {
-#endif
-
-#ifndef END_NAMESPACE
-#define END_NAMESPACE(ns)   } // ns
-#endif
-
-#ifndef DEFAULT
-#define DEFAULT(x)  = x
-#endif
-
-#ifndef ENUM
-#define ENUM(e)     enum e
-#endif
-
-#ifndef STRUCT
-#define STRUCT(s)   struct s
-#endif
-
+#ifdef PRINT_ERROR
+#define printe(...) fprintf(stderr, __VA_ARGS__)
 #else
-
-#define EXTERN_C    extern
-#define BEGIN_EXTERN_C
-#define END_EXTERN_C
-
-#define BEGIN_NAMESPACE(ns)
-#define END_NAMESPACE(ns)
-
-#ifndef DEFAULT
-#define DEFAULT(x)
+#define printe(...)
 #endif
 
-#ifndef ENUM
-#define ENUM(e)\
-typedef enum e e;\
-enum e
-#endif
-
-#ifndef STRUCT
-#define STRUCT(s)\
-typedef struct s s;\
-struct s
-#endif
-
-#endif // __cplusplus
-
 #endif // HV_DEF_H_

+ 0 - 2
base/hdir.cpp

@@ -1,7 +1,5 @@
 #include "hdir.h"
 
-#include <string.h>
-
 #include "hplatform.h"
 
 #ifdef OS_WIN

+ 3 - 1
base/hdir.h

@@ -50,6 +50,8 @@ int main(int argc, char* argv[]) {
 
 #include <list>
 
+#include "hexport.h"
+
 typedef struct hdir_s {
     char    name[256];
     char    type; // f:file d:dir l:link b:block c:char s:socket p:pipe
@@ -62,6 +64,6 @@ typedef struct hdir_s {
 } hdir_t;
 
 // listdir: same as ls on unix, dir on win
-int listdir(const char* dir, std::list<hdir_t>& dirs);
+HV_EXPORT int listdir(const char* dir, std::list<hdir_t>& dirs);
 
 #endif // HV_DIR_H_

+ 2 - 3
base/heap.h

@@ -1,9 +1,8 @@
 #ifndef HV_HEAP_H_
 #define HV_HEAP_H_
 
-#include <assert.h>
-
-#include "hdef.h"
+#include <assert.h> // for assert
+#include <stddef.h> // for NULL
 
 struct heap_node {
     struct heap_node* parent;

+ 3 - 1
base/herr.h

@@ -3,6 +3,8 @@
 
 #include <errno.h>
 
+#include "hexport.h"
+
 #ifndef SYS_NERR
 #define SYS_NERR    133
 #endif
@@ -119,7 +121,7 @@ extern "C" {
 #endif
 
 // errcode => errmsg
-const char* hv_strerror(int err);
+HV_EXPORT const char* hv_strerror(int err);
 
 #ifdef __cplusplus
 } // extern "C"

+ 29 - 30
base/hfile.h

@@ -1,16 +1,16 @@
 #ifndef HV_FILE_H_
 #define HV_FILE_H_
 
-#include <string>
+#include <string> // for std::string
 
-#include "hdef.h"
-#include "hbuf.h"
-#include "herr.h"
+#include "hplatform.h" // for stat
+#include "hdef.h" // for LF, CR
+#include "hbuf.h" // for HBuf
 
 class HFile {
 public:
     HFile() {
-        _fp = NULL;
+        fp = NULL;
     }
 
     ~HFile() {
@@ -19,47 +19,49 @@ public:
 
     int open(const char* filepath, const char* mode) {
         close();
-        strncpy(_filepath, filepath, MAX_PATH);
-        _fp = fopen(filepath, mode);
-        if (_fp == NULL) {
-            return ERR_OPEN_FILE;
-        }
-        return 0;
+        strncpy(this->filepath, filepath, MAX_PATH);
+        fp = fopen(filepath, mode);
+        return fp ? 0 : errno;
     }
 
     void close() {
-        if (_fp) {
-            fclose(_fp);
-            _fp = NULL;
+        if (fp) {
+            fclose(fp);
+            fp = NULL;
         }
     }
 
+    size_t read(void* ptr, size_t len) {
+        return fread(ptr, 1, len, fp);
+    }
+
+    size_t write(const void* ptr, size_t len) {
+        return fwrite(ptr, 1, len, fp);
+    }
+
     size_t size() {
         struct stat st;
-        stat(_filepath, &st);
+        memset(&st, 0, sizeof(st));
+        stat(filepath, &st);
         return st.st_size;
     }
 
-    size_t read(void* ptr, size_t len) {
-        return fread(ptr, 1, len, _fp);
-    }
-
     size_t readall(HBuf& buf) {
         size_t filesize = size();
         buf.resize(filesize);
-        return fread(buf.base, 1, filesize, _fp);
+        return fread(buf.base, 1, filesize, fp);
     }
 
     size_t readall(std::string& str) {
         size_t filesize = size();
         str.resize(filesize);
-        return fread((void*)str.data(), 1, filesize, _fp);
+        return fread((void*)str.data(), 1, filesize, fp);
     }
 
     bool readline(std::string& str) {
         str.clear();
         char ch;
-        while (fread(&ch, 1, 1, _fp)) {
+        while (fread(&ch, 1, 1, fp)) {
             if (ch == LF) {
                 // unix: LF
                 return true;
@@ -67,9 +69,9 @@ public:
             if (ch == CR) {
                 // dos: CRLF
                 // read LF
-                if (fread(&ch, 1, 1, _fp) && ch != LF) {
+                if (fread(&ch, 1, 1, fp) && ch != LF) {
                     // mac: CR
-                    fseek(_fp, -1, SEEK_CUR);
+                    fseek(fp, -1, SEEK_CUR);
                 }
                 return true;
             }
@@ -78,12 +80,9 @@ public:
         return str.length() != 0;
     }
 
-    size_t write(const void* ptr, size_t len) {
-        return fwrite(ptr, 1, len, _fp);
-    }
-
-    char  _filepath[MAX_PATH];
-    FILE* _fp;
+public:
+    char  filepath[MAX_PATH];
+    FILE* fp;
 };
 
 #endif // HV_FILE_H_

+ 2 - 2
base/hlog.c

@@ -294,7 +294,7 @@ int logger_print(logger_t* logger, int level, const char* fmt, ...) {
     return len;
 }
 
-logger_t* default_logger() {
+logger_t* hv_default_logger() {
     static logger_t* s_logger = NULL;
     if (s_logger == NULL) {
         s_logger = logger_create();
@@ -311,7 +311,7 @@ void stderr_logger(int loglevel, const char* buf, int len) {
 }
 
 void file_logger(int loglevel, const char* buf, int len) {
-    logger_t* logger = default_logger();
+    logger_t* logger = hv_default_logger();
     FILE* fp = shift_logfile(logger);
     if (fp) {
         fwrite(buf, 1, len, fp);

+ 21 - 19
base/hlog.h

@@ -5,6 +5,8 @@
  * hlog is thread-safe
  */
 
+#include "hexport.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -54,35 +56,35 @@ typedef enum {
 // network_logger() see event/nlog.h
 typedef void (*logger_handler)(int loglevel, const char* buf, int len);
 
-void stdout_logger(int loglevel, const char* buf, int len);
-void stderr_logger(int loglevel, const char* buf, int len);
-void file_logger(int loglevel, const char* buf, int len);
+HV_EXPORT void stdout_logger(int loglevel, const char* buf, int len);
+HV_EXPORT void stderr_logger(int loglevel, const char* buf, int len);
+HV_EXPORT void file_logger(int loglevel, const char* buf, int len);
 // network_logger implement see event/nlog.h
-// void network_logger(int loglevel, const char* buf, int len);
+// HV_EXPORT void network_logger(int loglevel, const char* buf, int len);
 
 typedef struct logger_s logger_t;
-logger_t* logger_create();
-void logger_destroy(logger_t* logger);
+HV_EXPORT logger_t* logger_create();
+HV_EXPORT void logger_destroy(logger_t* logger);
 
-void logger_set_handler(logger_t* logger, logger_handler fn);
-void logger_set_level(logger_t* logger, int level);
-void logger_set_max_bufsize(logger_t* logger, unsigned int bufsize);
-void logger_enable_color(logger_t* logger, int on);
-int  logger_print(logger_t* logger, int level, const char* fmt, ...);
+HV_EXPORT void logger_set_handler(logger_t* logger, logger_handler fn);
+HV_EXPORT void logger_set_level(logger_t* logger, int level);
+HV_EXPORT void logger_set_max_bufsize(logger_t* logger, unsigned int bufsize);
+HV_EXPORT void logger_enable_color(logger_t* logger, int on);
+HV_EXPORT int  logger_print(logger_t* logger, int level, const char* fmt, ...);
 
 // below for file logger
-void logger_set_file(logger_t* logger, const char* filepath);
-void logger_set_max_filesize(logger_t* logger, unsigned long long filesize);
-void logger_set_remain_days(logger_t* logger, int days);
-void logger_enable_fsync(logger_t* logger, int on);
-void logger_fsync(logger_t* logger);
-const char* logger_get_cur_file(logger_t* logger);
+HV_EXPORT void logger_set_file(logger_t* logger, const char* filepath);
+HV_EXPORT void logger_set_max_filesize(logger_t* logger, unsigned long long filesize);
+HV_EXPORT void logger_set_remain_days(logger_t* logger, int days);
+HV_EXPORT void logger_enable_fsync(logger_t* logger, int on);
+HV_EXPORT void logger_fsync(logger_t* logger);
+HV_EXPORT const char* logger_get_cur_file(logger_t* logger);
 
 // hlog: default logger instance
-logger_t* default_logger();
+HV_EXPORT logger_t* hv_default_logger();
 
 // macro hlog*
-#define hlog default_logger()
+#define hlog hv_default_logger()
 #define hlog_set_file(filepath)         logger_set_file(hlog, filepath)
 #define hlog_set_level(level)           logger_set_level(hlog, level)
 #define hlog_set_max_filesize(filesize) logger_set_max_filesize(hlog, filesize)

+ 1 - 0
base/hmath.h

@@ -1,5 +1,6 @@
 #ifndef HV_MATH_H_
 #define HV_MATH_H_
+
 #include <math.h>
 
 static inline unsigned long floor2e(unsigned long num) {

+ 3 - 2
base/hmutex.h

@@ -1,6 +1,7 @@
 #ifndef HV_MUTEX_H_
 #define HV_MUTEX_H_
 
+#include "hexport.h"
 #include "hplatform.h"
 #include "htime.h"
 
@@ -200,7 +201,7 @@ using std::condition_variable;
 using std::lock_guard;
 using std::unique_lock;
 
-namespace hv {
+BEGIN_NAMESPACE_HV
 
 class MutexLock {
 public:
@@ -238,7 +239,7 @@ protected:
     hrwlock_t   _rwlock;
 };
 
-} // end namespace
+END_NAMESPACE_HV
 
 #endif // __cplusplus
 

+ 0 - 15
base/hplatform.h

@@ -61,21 +61,6 @@
 #endif
 // __clang__
 
-// HV_EXPORT
-#ifdef HV_STATICLIB
-    #define HV_EXPORT
-#elif defined(OS_WIN)
-    #if defined(HV_EXPORTS) || defined(hv_EXPORTS)
-        #define HV_EXPORT  __declspec(dllexport)
-    #else
-        #define HV_EXPORT  __declspec(dllimport)
-    #endif
-#elif defined(__GNUC__)
-    #define HV_EXPORT  __attribute__((visibility("default")))
-#else
-    #define HV_EXPORT
-#endif
-
 // ARCH
 #if defined(__i386) || defined(__i386__) || defined(_M_IX86)
     #define ARCH_X86

+ 0 - 1
base/hproc.h

@@ -2,7 +2,6 @@
 #define HV_PROC_H_
 
 #include "hplatform.h"
-#include "hdef.h"
 
 typedef struct proc_ctx_s {
     pid_t           pid; // tid in win32

+ 3 - 3
base/hscope.h

@@ -20,15 +20,15 @@ class ScopeCleanup {
 public:
     template<typename Fn, typename... Args>
     ScopeCleanup(Fn&& fn, Args&&... args) {
-        cleanup_ = std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...);
+        _cleanup = std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...);
     }
 
     ~ScopeCleanup() {
-        cleanup_();
+        _cleanup();
     }
 
 private:
-    Function cleanup_;
+    Function _cleanup;
 };
 
 template<typename T>

+ 2 - 0
base/hsocket.c

@@ -1,5 +1,7 @@
 #include "hsocket.h"
 
+#include "hdef.h"
+
 static inline int socket_errno_negative() {
     int err = socket_errno();
     return err > 0 ? -err : -1;

+ 14 - 14
base/hsocket.h

@@ -1,8 +1,8 @@
 #ifndef HV_SOCKET_H_
 #define HV_SOCKET_H_
 
+#include "hexport.h"
 #include "hplatform.h"
-#include "hdef.h"
 
 #ifdef ENABLE_UDS
     #include <sys/un.h> // import struct sockaddr_un
@@ -24,7 +24,7 @@ static inline int socket_errno() {
     return errno;
 #endif
 }
-const char* socket_strerror(int err);
+HV_EXPORT const char* socket_strerror(int err);
 
 #ifdef OS_WIN
 typedef int socklen_t;
@@ -63,7 +63,7 @@ typedef union {
 
 // @param host: domain or ip
 // @retval 0:succeed
-int Resolver(const char* host, sockaddr_u* addr);
+HV_EXPORT int Resolver(const char* host, sockaddr_u* addr);
 
 static inline const char* sockaddr_ip(sockaddr_u* addr, char *ip, int len) {
     if (addr->sa.sa_family == AF_INET) {
@@ -173,31 +173,31 @@ static inline void sockaddr_print(sockaddr_u* addr) {
 // socket -> setsockopt -> bind
 // @param type: SOCK_STREAM(tcp) SOCK_DGRAM(udp)
 // @return sockfd
-int Bind(int port, const char* host DEFAULT(ANYADDR), int type DEFAULT(SOCK_STREAM));
+HV_EXPORT int Bind(int port, const char* host DEFAULT(ANYADDR), int type DEFAULT(SOCK_STREAM));
 
 // Bind -> listen
 // @return listenfd
-int Listen(int port, const char* host DEFAULT(ANYADDR));
+HV_EXPORT int Listen(int port, const char* host DEFAULT(ANYADDR));
 
 // @return connfd
 // Resolver -> socket -> nonblocking -> connect
-int Connect(const char* host, int port, int nonblock DEFAULT(0));
+HV_EXPORT int Connect(const char* host, int port, int nonblock DEFAULT(0));
 // Connect(host, port, 1)
-int ConnectNonblock(const char* host, int port);
+HV_EXPORT int ConnectNonblock(const char* host, int port);
 // Connect(host, port, 1) -> select -> blocking
 #define DEFAULT_CONNECT_TIMEOUT 5000 // ms
-int ConnectTimeout(const char* host, int port, int ms DEFAULT(DEFAULT_CONNECT_TIMEOUT));
+HV_EXPORT int ConnectTimeout(const char* host, int port, int ms DEFAULT(DEFAULT_CONNECT_TIMEOUT));
 
 #ifdef ENABLE_UDS
-int BindUnix(const char* path, int type DEFAULT(SOCK_STREAM));
-int ListenUnix(const char* path);
-int ConnectUnix(const char* path, int nonblock DEFAULT(0));
-int ConnectUnixNonblock(const char* path);
-int ConnectUnixTimeout(const char* path, int ms DEFAULT(DEFAULT_CONNECT_TIMEOUT));
+HV_EXPORT int BindUnix(const char* path, int type DEFAULT(SOCK_STREAM));
+HV_EXPORT int ListenUnix(const char* path);
+HV_EXPORT int ConnectUnix(const char* path, int nonblock DEFAULT(0));
+HV_EXPORT int ConnectUnixNonblock(const char* path);
+HV_EXPORT int ConnectUnixTimeout(const char* path, int ms DEFAULT(DEFAULT_CONNECT_TIMEOUT));
 #endif
 
 // Just implement Socketpair(AF_INET, SOCK_STREAM, 0, sv);
-int Socketpair(int family, int type, int protocol, int sv[2]);
+HV_EXPORT int Socketpair(int family, int type, int protocol, int sv[2]);
 
 static inline int tcp_nodelay(int sockfd, int on DEFAULT(1)) {
     return setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(int));

+ 13 - 12
base/hstring.h

@@ -5,6 +5,7 @@
 #include <vector>
 #include <sstream>
 
+#include "hexport.h"
 #include "hbase.h"
 #include "hmap.h"
 
@@ -40,25 +41,25 @@ static inline T from_string(const std::string& str) {
 #define SPACE_CHARS     " \t\r\n"
 #define PAIR_CHARS      "{}[]()<>\"\"\'\'``"
 
-string asprintf(const char* fmt, ...);
+HV_EXPORT string asprintf(const char* fmt, ...);
 // x,y,z
-StringList split(const string& str, char delim = ',');
+HV_EXPORT StringList split(const string& str, char delim = ',');
 // user=amdin&pswd=123456
-hv::KeyValue splitKV(const string& str, char kv_kv = '&', char k_v = '=');
-string trim(const string& str, const char* chars = SPACE_CHARS);
-string trimL(const string& str, const char* chars = SPACE_CHARS);
-string trimR(const string& str, const char* chars = SPACE_CHARS);
-string trim_pairs(const string& str, const char* pairs = PAIR_CHARS);
-string replace(const string& str, const string& find, const string& rep);
+HV_EXPORT hv::KeyValue splitKV(const string& str, char kv_kv = '&', char k_v = '=');
+HV_EXPORT string trim(const string& str, const char* chars = SPACE_CHARS);
+HV_EXPORT string trimL(const string& str, const char* chars = SPACE_CHARS);
+HV_EXPORT string trimR(const string& str, const char* chars = SPACE_CHARS);
+HV_EXPORT string trim_pairs(const string& str, const char* pairs = PAIR_CHARS);
+HV_EXPORT string replace(const string& str, const string& find, const string& rep);
 
 // str=/mnt/share/image/test.jpg
 // basename=test.jpg
 // dirname=/mnt/share/image
 // filename=test
 // suffixname=jpg
-string basename(const string& str);
-string dirname(const string& str);
-string filename(const string& str);
-string suffixname(const string& str);
+HV_EXPORT string basename(const string& str);
+HV_EXPORT string dirname(const string& str);
+HV_EXPORT string filename(const string& str);
+HV_EXPORT string suffixname(const string& str);
 
 #endif // HV_STRING_H_

+ 0 - 1
base/hthread.h

@@ -2,7 +2,6 @@
 #define HV_THREAD_H_
 
 #include "hplatform.h"
-#include "hdef.h"
 
 #ifdef OS_WIN
 #define hv_getpid   (long)GetCurrentProcessId

+ 17 - 17
base/htime.h

@@ -1,8 +1,8 @@
 #ifndef HV_TIME_H_
 #define HV_TIME_H_
 
+#include "hexport.h"
 #include "hplatform.h"
-#include "hdef.h"
 
 BEGIN_EXTERN_C
 
@@ -72,7 +72,7 @@ static inline void msleep(unsigned int ms) {
 #endif
 
 // ms
-unsigned int gettick();
+HV_EXPORT unsigned int gettick();
 
 static inline unsigned long long gettimeofday_ms() {
     struct timeval tv;
@@ -81,35 +81,35 @@ static inline unsigned long long gettimeofday_ms() {
 }
 
 // us
-unsigned long long gethrtime_us();
+HV_EXPORT unsigned long long gethrtime_us();
 
-datetime_t datetime_now();
-time_t     datetime_mktime(datetime_t* dt);
+HV_EXPORT datetime_t datetime_now();
+HV_EXPORT time_t     datetime_mktime(datetime_t* dt);
 
-datetime_t* datetime_past(datetime_t* dt, int days DEFAULT(1));
-datetime_t* datetime_future(datetime_t* dt, int days DEFAULT(1));
+HV_EXPORT datetime_t* datetime_past(datetime_t* dt, int days DEFAULT(1));
+HV_EXPORT datetime_t* datetime_future(datetime_t* dt, int days DEFAULT(1));
 
 #define TIME_FMT            "%02d:%02d:%02d"
 #define TIME_FMT_BUFLEN     12
-char* duration_fmt(int sec, char* buf);
+HV_EXPORT char* duration_fmt(int sec, char* buf);
 
 #define DATETIME_FMT        "%04d-%02d-%02d %02d:%02d:%02d.%03d"
 #define DATETIME_FMT_BUFLEN 24
-char* datetime_fmt(datetime_t* dt, char* buf);
+HV_EXPORT char* datetime_fmt(datetime_t* dt, char* buf);
 
 #define GMTIME_FMT          "%.3s, %02d %.3s %04d %02d:%02d:%02d GMT"
 #define GMTIME_FMT_BUFLEN   30
-char* gmtime_fmt(time_t time, char* buf);
+HV_EXPORT char* gmtime_fmt(time_t time, char* buf);
 
-int days_of_month(int month, int year);
+HV_EXPORT int days_of_month(int month, int year);
 
-int month_atoi(const char* month);
-const char* month_itoa(int month);
+HV_EXPORT int month_atoi(const char* month);
+HV_EXPORT const char* month_itoa(int month);
 
-int weekday_atoi(const char* weekday);
-const char* weekday_itoa(int weekday);
+HV_EXPORT int weekday_atoi(const char* weekday);
+HV_EXPORT const char* weekday_itoa(int weekday);
 
-datetime_t hv_compile_datetime();
+HV_EXPORT datetime_t hv_compile_datetime();
 
 /*
  * minute   hour    day     week    month       action
@@ -120,7 +120,7 @@ datetime_t hv_compile_datetime();
  *  30      1       -1       0      -1          cron.weekly
  *  30      1        1      -1      10          cron.yearly
  */
-time_t cron_next_timeout(int minute, int hour, int day, int week, int month);
+HV_EXPORT time_t cron_next_timeout(int minute, int hour, int day, int week, int month);
 
 END_EXTERN_C
 

+ 4 - 2
base/hurl.h

@@ -3,7 +3,9 @@
 
 #include <string>
 
-std::string url_escape(const char* istr);
-std::string url_unescape(const char* istr);
+#include "hexport.h"
+
+HV_EXPORT std::string url_escape(const char* istr);
+HV_EXPORT std::string url_unescape(const char* istr);
 
 #endif // HV_URL_H_

+ 4 - 3
base/hversion.h

@@ -1,6 +1,7 @@
 #ifndef HV_VERSION_H_
 #define HV_VERSION_H_
 
+#include "hexport.h"
 #include "hdef.h"
 
 BEGIN_EXTERN_C
@@ -20,13 +21,13 @@ static inline const char* hv_version() {
     return HV_VERSION_STRING;
 }
 
-const char* hv_compile_version();
+HV_EXPORT const char* hv_compile_version();
 
 // 1.2.3.4 => 0x01020304
-int version_atoi(const char* str);
+HV_EXPORT int version_atoi(const char* str);
 
 // 0x01020304 => 1.2.3.4
-void version_itoa(int hex, char* str);
+HV_EXPORT void version_itoa(int hex, char* str);
 
 END_EXTERN_C
 

+ 0 - 4
base/ifconfig.cpp

@@ -1,9 +1,5 @@
 #include "ifconfig.h"
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
 #include "hplatform.h"
 
 #ifdef OS_LINUX

+ 3 - 1
base/ifconfig.h

@@ -3,6 +3,8 @@
 
 #include <vector>
 
+#include "hexport.h"
+
 #ifdef _MSC_VER
 #pragma comment(lib, "iphlpapi.lib")
 #pragma comment(lib, "ws2_32.lib")
@@ -29,6 +31,6 @@ typedef struct ifconfig_s {
                 item.mac);
     }
  */
-int ifconfig(std::vector<ifconfig_t>& ifcs);
+HV_EXPORT int ifconfig(std::vector<ifconfig_t>& ifcs);
 
 #endif // HV_IFCONFIG_H_

+ 10 - 2
base/list.h

@@ -1,8 +1,6 @@
 #ifndef _LINUX_LIST_H
 #define _LINUX_LIST_H
 
-#include "hdef.h"
-
 /*
  * Simple doubly linked list implementation.
  *
@@ -13,6 +11,16 @@
  * using the generic single-entry routines.
  */
 
+#include <stddef.h>
+
+#ifndef prefetch
+#ifdef __GNUC__
+    #define prefetch(x) __builtin_prefetch(x)
+#else
+    #define prefetch(x) (void)0
+#endif
+#endif
+
 struct list_head {
 	struct list_head *next, *prev;
 };

+ 2 - 1
base/queue.h

@@ -9,10 +9,11 @@
  */
 
 #include <assert.h> // for assert
+#include <stddef.h> // for NULL
 #include <stdlib.h> // for malloc,realloc,free
 #include <string.h> // for memset,memmove
 
-#include "hbase.h"
+#include "hbase.h"  // for HV_ALLOC, HV_FREE
 
 #define QUEUE_INIT_SIZE     16
 

+ 6 - 8
base/ssl_ctx.h

@@ -1,17 +1,15 @@
 #ifndef HV_SSL_CTX_H
 #define HV_SSL_CTX_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "hexport.h"
+
+BEGIN_EXTERN_C
 
 extern void* g_ssl_ctx; // for SSL_CTX
 
-int ssl_ctx_init(const char* crt_file, const char* key_file, const char* ca_file);
-int ssl_ctx_destory();
+HV_EXPORT int ssl_ctx_init(const char* crt_file, const char* key_file, const char* ca_file);
+HV_EXPORT int ssl_ctx_destory();
 
-#ifdef __cplusplus
-}
-#endif
+END_EXTERN_C
 
 #endif // HV_SSL_CTX_H

+ 5 - 3
consul/consul.h

@@ -4,6 +4,8 @@
 #include <vector>
 #include <string.h>
 
+#include "hexport.h"
+
 typedef struct consul_node_s {
     // node
     char ip[32];
@@ -45,8 +47,8 @@ typedef struct consul_health_s {
     }
 } consul_health_t;
 
-int register_service(consul_node_t* node, consul_service_t* service, consul_health_t* health);
-int deregister_service(consul_node_t* node, consul_service_t* service);
-int discover_services(consul_node_t* node, const char* service_name, std::vector<consul_service_t>& services);
+HV_EXPORT int register_service(consul_node_t* node, consul_service_t* service, consul_health_t* health);
+HV_EXPORT int deregister_service(consul_node_t* node, consul_service_t* service);
+HV_EXPORT int discover_services(consul_node_t* node, const char* service_name, std::vector<consul_service_t>& services);
 
 #endif // CONSUL_H_

+ 76 - 65
event/hloop.h

@@ -1,10 +1,10 @@
 #ifndef HV_LOOP_H_
 #define HV_LOOP_H_
 
+#include "hexport.h"
+#include "hplatform.h"
 #include "hdef.h"
 
-BEGIN_EXTERN_C
-
 typedef struct hloop_s  hloop_t;
 typedef struct hevent_s hevent_t;
 
@@ -87,27 +87,31 @@ typedef enum {
     HIO_TYPE_SOCKET  = 0x00FFFF00,
 } hio_type_e;
 
+BEGIN_EXTERN_C
+
 // loop
 #define HLOOP_FLAG_RUN_ONCE                     0x00000001
 #define HLOOP_FLAG_AUTO_FREE                    0x00000002
 #define HLOOP_FLAG_QUIT_WHEN_NO_ACTIVE_EVENTS   0x00000004
-hloop_t* hloop_new(int flags DEFAULT(HLOOP_FLAG_AUTO_FREE));
+HV_EXPORT hloop_t* hloop_new(int flags DEFAULT(HLOOP_FLAG_AUTO_FREE));
+
 // WARN: Forbid to call hloop_free if HLOOP_INIT_FLAG_AUTO_FREE set.
-void hloop_free(hloop_t** pp);
+HV_EXPORT void hloop_free(hloop_t** pp);
+
 // NOTE: when no active events, loop will quit if HLOOP_FLAG_QUIT_WHEN_NO_ACTIVE_EVENTS set.
-int hloop_run(hloop_t* loop);
-int hloop_stop(hloop_t* loop);
-int hloop_pause(hloop_t* loop);
-int hloop_resume(hloop_t* loop);
+HV_EXPORT int hloop_run(hloop_t* loop);
+HV_EXPORT int hloop_stop(hloop_t* loop);
+HV_EXPORT int hloop_pause(hloop_t* loop);
+HV_EXPORT int hloop_resume(hloop_t* loop);
 
-void     hloop_update_time(hloop_t* loop);
-uint64_t hloop_now(hloop_t* loop);          // s
-uint64_t hloop_now_ms(hloop_t* loop);       // ms
-uint64_t hloop_now_hrtime(hloop_t* loop);   // us
+HV_EXPORT void     hloop_update_time(hloop_t* loop);
+HV_EXPORT uint64_t hloop_now(hloop_t* loop);          // s
+HV_EXPORT uint64_t hloop_now_ms(hloop_t* loop);       // ms
+HV_EXPORT uint64_t hloop_now_hrtime(hloop_t* loop);   // us
 
 // userdata
-void  hloop_set_userdata(hloop_t* loop, void* userdata);
-void* hloop_userdata(hloop_t* loop);
+HV_EXPORT void  hloop_set_userdata(hloop_t* loop, void* userdata);
+HV_EXPORT void* hloop_userdata(hloop_t* loop);
 
 // custom_event
 /*
@@ -119,15 +123,15 @@ void* hloop_userdata(hloop_t* loop);
  * hloop_post_event(loop, &ev);
  */
 // NOTE: hloop_post_event is thread-safe
-void hloop_post_event(hloop_t* loop, hevent_t* ev);
+HV_EXPORT void hloop_post_event(hloop_t* loop, hevent_t* ev);
 
 // idle
-hidle_t*    hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat DEFAULT(INFINITE));
-void        hidle_del(hidle_t* idle);
+HV_EXPORT hidle_t* hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat DEFAULT(INFINITE));
+HV_EXPORT void     hidle_del(hidle_t* idle);
 
 // timer
 // @param timeout: unit(ms)
-htimer_t*   htimer_add(hloop_t* loop, htimer_cb cb, uint32_t timeout, uint32_t repeat DEFAULT(INFINITE));
+HV_EXPORT htimer_t* htimer_add(hloop_t* loop, htimer_cb cb, uint32_t timeout, uint32_t repeat DEFAULT(INFINITE));
 /*
  * minute   hour    day     week    month       cb
  * 0~59     0~23    1~31    0~6     1~12
@@ -137,11 +141,12 @@ htimer_t*   htimer_add(hloop_t* loop, htimer_cb cb, uint32_t timeout, uint32_t r
  *  30      1       -1       5      -1          cron.weekly
  *  30      1        1      -1      10          cron.yearly
  */
-htimer_t*   htimer_add_period(hloop_t* loop, htimer_cb cb,
-                int8_t minute DEFAULT(0),  int8_t hour  DEFAULT(-1), int8_t day DEFAULT(-1),
-                int8_t week   DEFAULT(-1), int8_t month DEFAULT(-1), uint32_t repeat DEFAULT(INFINITE));
-void        htimer_del(htimer_t* timer);
-void        htimer_reset(htimer_t* timer);
+HV_EXPORT htimer_t* htimer_add_period(hloop_t* loop, htimer_cb cb,
+                        int8_t minute DEFAULT(0),  int8_t hour  DEFAULT(-1), int8_t day DEFAULT(-1),
+                        int8_t week   DEFAULT(-1), int8_t month DEFAULT(-1), uint32_t repeat DEFAULT(INFINITE));
+
+HV_EXPORT void htimer_del(htimer_t* timer);
+HV_EXPORT void htimer_reset(htimer_t* timer);
 
 // io
 //-----------------------low-level apis---------------------------------------
@@ -167,72 +172,78 @@ const char* hio_engine() {
 #endif
 }
 */
-const char* hio_engine();
-hio_t* hio_get(hloop_t* loop, int fd);
-int    hio_add(hio_t* io, hio_cb cb, int events DEFAULT(HV_READ));
-int    hio_del(hio_t* io, int events DEFAULT(HV_RDWR));
-
-int hio_fd    (hio_t* io);
-int hio_error (hio_t* io);
-hio_type_e hio_type(hio_t* io);
-struct sockaddr* hio_localaddr(hio_t* io);
-struct sockaddr* hio_peeraddr (hio_t* io);
-
-void hio_set_readbuf(hio_t* io, void* buf, size_t len);
-// ssl
-int  hio_enable_ssl(hio_t* io);
-
-void hio_setcb_accept   (hio_t* io, haccept_cb  accept_cb);
-void hio_setcb_connect  (hio_t* io, hconnect_cb connect_cb);
-void hio_setcb_read     (hio_t* io, hread_cb    read_cb);
-void hio_setcb_write    (hio_t* io, hwrite_cb   write_cb);
-void hio_setcb_close    (hio_t* io, hclose_cb   close_cb);
-
-int hio_read   (hio_t* io);
-int hio_write  (hio_t* io, const void* buf, size_t len);
-int hio_close  (hio_t* io);
-int hio_accept (hio_t* io);
-int hio_connect(hio_t* io);
+HV_EXPORT const char* hio_engine();
+
+HV_EXPORT hio_t* hio_get(hloop_t* loop, int fd);
+HV_EXPORT int    hio_add(hio_t* io, hio_cb cb, int events DEFAULT(HV_READ));
+HV_EXPORT int    hio_del(hio_t* io, int events DEFAULT(HV_RDWR));
+
+// hio_t fields
+HV_EXPORT int hio_fd    (hio_t* io);
+HV_EXPORT int hio_error (hio_t* io);
+HV_EXPORT hio_type_e hio_type(hio_t* io);
+HV_EXPORT struct sockaddr* hio_localaddr(hio_t* io);
+HV_EXPORT struct sockaddr* hio_peeraddr (hio_t* io);
+
+// TODO: One loop per thread, one readbuf per loop.
+// But you can pass in your own readbuf instead of the default readbuf to avoid memcopy.
+HV_EXPORT void hio_set_readbuf(hio_t* io, void* buf, size_t len);
+// Enable SSL/TLS is so easy :)
+HV_EXPORT int  hio_enable_ssl(hio_t* io);
+
+// set callbacks
+HV_EXPORT void hio_setcb_accept   (hio_t* io, haccept_cb  accept_cb);
+HV_EXPORT void hio_setcb_connect  (hio_t* io, hconnect_cb connect_cb);
+HV_EXPORT void hio_setcb_read     (hio_t* io, hread_cb    read_cb);
+HV_EXPORT void hio_setcb_write    (hio_t* io, hwrite_cb   write_cb);
+HV_EXPORT void hio_setcb_close    (hio_t* io, hclose_cb   close_cb);
+
+// Nonblocking, poll IO events in the loop to call corresponding callback.
+HV_EXPORT int hio_accept (hio_t* io);
+HV_EXPORT int hio_connect(hio_t* io);
+HV_EXPORT int hio_read   (hio_t* io);
+HV_EXPORT int hio_write  (hio_t* io, const void* buf, size_t len);
+HV_EXPORT int hio_close  (hio_t* io);
 
 //------------------high-level apis-------------------------------------------
 // hio_get -> hio_set_readbuf -> hio_setcb_read -> hio_read
-hio_t* hread    (hloop_t* loop, int fd, void* buf, size_t len, hread_cb read_cb);
+HV_EXPORT hio_t* hread    (hloop_t* loop, int fd, void* buf, size_t len, hread_cb read_cb);
 // hio_get -> hio_setcb_write -> hio_write
-hio_t* hwrite   (hloop_t* loop, int fd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
+HV_EXPORT hio_t* hwrite   (hloop_t* loop, int fd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
 // hio_get -> hio_close
-void   hclose   (hloop_t* loop, int fd);
+HV_EXPORT void   hclose   (hloop_t* loop, int fd);
 
 // tcp
 // hio_get -> hio_setcb_accept -> hio_accept
-hio_t* haccept  (hloop_t* loop, int listenfd, haccept_cb accept_cb);
+HV_EXPORT hio_t* haccept  (hloop_t* loop, int listenfd, haccept_cb accept_cb);
 // hio_get -> hio_setcb_connect -> hio_connect
-hio_t* hconnect (hloop_t* loop, int connfd,   hconnect_cb connect_cb);
+HV_EXPORT hio_t* hconnect (hloop_t* loop, int connfd,   hconnect_cb connect_cb);
 // hio_get -> hio_set_readbuf -> hio_setcb_read -> hio_read
-hio_t* hrecv    (hloop_t* loop, int connfd, void* buf, size_t len, hread_cb read_cb);
+HV_EXPORT hio_t* hrecv    (hloop_t* loop, int connfd, void* buf, size_t len, hread_cb read_cb);
 // hio_get -> hio_setcb_write -> hio_write
-hio_t* hsend    (hloop_t* loop, int connfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
+HV_EXPORT hio_t* hsend    (hloop_t* loop, int connfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
 
 // udp/ip
 // for HIO_TYPE_IP
-void hio_set_type(hio_t* io, hio_type_e type);
-void hio_set_localaddr(hio_t* io, struct sockaddr* addr, int addrlen);
-void hio_set_peeraddr (hio_t* io, struct sockaddr* addr, int addrlen);
+HV_EXPORT void hio_set_type(hio_t* io, hio_type_e type);
+HV_EXPORT void hio_set_localaddr(hio_t* io, struct sockaddr* addr, int addrlen);
+HV_EXPORT void hio_set_peeraddr (hio_t* io, struct sockaddr* addr, int addrlen);
 // NOTE: must call hio_set_peeraddr before hrecvfrom/hsendto
 // hio_get -> hio_set_readbuf -> hio_setcb_read -> hio_read
-hio_t* hrecvfrom (hloop_t* loop, int sockfd, void* buf, size_t len, hread_cb read_cb);
+HV_EXPORT hio_t* hrecvfrom (hloop_t* loop, int sockfd, void* buf, size_t len, hread_cb read_cb);
 // hio_get -> hio_setcb_write -> hio_write
-hio_t* hsendto   (hloop_t* loop, int sockfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
+HV_EXPORT hio_t* hsendto   (hloop_t* loop, int sockfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
 
 //----------------- top-level apis---------------------------------------------
 // @tcp_server: socket -> bind -> listen -> haccept
-hio_t* create_tcp_server (hloop_t* loop, const char* host, int port, haccept_cb accept_cb);
+HV_EXPORT hio_t* create_tcp_server (hloop_t* loop, const char* host, int port, haccept_cb accept_cb);
 // @tcp_client: resolver -> socket -> hio_get -> hio_set_peeraddr -> hconnect
-hio_t* create_tcp_client (hloop_t* loop, const char* host, int port, hconnect_cb connect_cb);
+HV_EXPORT hio_t* create_tcp_client (hloop_t* loop, const char* host, int port, hconnect_cb connect_cb);
 
 // @udp_server: socket -> bind -> hio_get
-hio_t* create_udp_server (hloop_t* loop, const char* host, int port);
+HV_EXPORT hio_t* create_udp_server (hloop_t* loop, const char* host, int port);
 // @udp_client: resolver -> socket -> hio_get -> hio_set_peeraddr
-hio_t* create_udp_client (hloop_t* loop, const char* host, int port);
+HV_EXPORT hio_t* create_udp_client (hloop_t* loop, const char* host, int port);
 
 END_EXTERN_C
 

+ 7 - 3
event/nlog.h

@@ -17,12 +17,16 @@
     hloop_run(&loop);
  */
 
-#include "hlog.h"
+#include "hexport.h"
 #include "hloop.h"
 
 #define DEFAULT_LOG_PORT    10514
 
-void network_logger(int loglevel, const char* buf, int len);
-hio_t* nlog_listen(hloop_t* loop, int port);
+BEGIN_EXTERN_C
+
+HV_EXPORT void network_logger(int loglevel, const char* buf, int len);
+HV_EXPORT hio_t* nlog_listen(hloop_t* loop, int port);
+
+END_EXTERN_C
 
 #endif // HV_NLOG_H_

+ 5 - 3
event/nmap.h

@@ -2,6 +2,8 @@
 #define HV_NMAP_H_
 
 #include <map>
+
+#include "hexport.h"
 #include "hsocket.h"
 
 // addr => 0:down 1:up
@@ -12,8 +14,8 @@ typedef std::map<uint32_t, int> Nmap;
 // segment24: 192.168.1.x
 
 // @return up_cnt
-int nmap_discover(Nmap* nmap);
-int segment_discover(const char* segment16, Nmap* nmap);
-int host_discover(const char* segment24, Nmap* nmap);
+HV_EXPORT int nmap_discover(Nmap* nmap);
+HV_EXPORT int segment_discover(const char* segment16, Nmap* nmap);
+HV_EXPORT int host_discover(const char* segment24, Nmap* nmap);
 
 #endif // HV_NMAP_H_

+ 1 - 2
event/noevent.c

@@ -1,7 +1,6 @@
 #include "iowatcher.h"
 
 #ifdef EVENT_NOEVENT
-#include "htime.h"
 int iowatcher_init(hloop_t* loop) {
     return 0;
 }
@@ -19,7 +18,7 @@ int iowatcher_del_event(hloop_t* loop, int fd, int events) {
 }
 
 int iowatcher_poll_events(hloop_t* loop, int timeout) {
-    msleep(timeout);
+    hv_delay(timeout);
     return 0;
 }
 

+ 1 - 0
examples/hloop_test.c

@@ -1,5 +1,6 @@
 #include "hloop.h"
 #include "hbase.h"
+#include "hlog.h"
 #include "nlog.h"
 
 void mylogger(int loglevel, const char* buf, int len) {

+ 122 - 0
hexport.h

@@ -0,0 +1,122 @@
+#ifndef HV_EXPORT_H_
+#define HV_EXPORT_H_
+
+// HV_EXPORT
+#ifdef HV_STATICLIB
+    #define HV_EXPORT
+#elif defined(_WIN32)
+    #if defined(HV_EXPORTS) || defined(hv_EXPORTS)
+        #define HV_EXPORT  __declspec(dllexport)
+    #else
+        #define HV_EXPORT  __declspec(dllimport)
+    #endif
+#elif defined(__GNUC__)
+    #define HV_EXPORT  __attribute__((visibility("default")))
+#else
+    #define HV_EXPORT
+#endif
+
+// DEPRECATED
+#if defined(__GNUC__) || defined(__clang__)
+    #define DEPRECATED __attribute__((visibility("deprecated")))
+#else
+    #define DEPRECATED
+#endif
+
+// @param[IN | OUT | INOUT]
+#ifndef IN
+#define IN
+#endif
+
+#ifndef OUT
+#define OUT
+#endif
+
+#ifndef INOUT
+#define INOUT
+#endif
+
+// @field[OPTIONAL | REQUIRED | REPEATED]
+#ifndef OPTIONAL
+#define OPTIONAL
+#endif
+
+#ifndef REQUIRED
+#define REQUIRED
+#endif
+
+#ifndef REPEATED
+#define REPEATED
+#endif
+
+#ifdef __cplusplus
+
+#ifndef EXTERN_C
+#define EXTERN_C            extern "C"
+#endif
+
+#ifndef BEGIN_EXTERN_C
+#define BEGIN_EXTERN_C      extern "C" {
+#endif
+
+#ifndef END_EXTERN_C
+#define END_EXTERN_C        } // extern "C"
+#endif
+
+#ifndef BEGIN_NAMESPACE
+#define BEGIN_NAMESPACE(ns) namespace ns {
+#endif
+
+#ifndef END_NAMESPACE
+#define END_NAMESPACE(ns)   } // namespace ns
+#endif
+
+#ifndef USING_NAMESPACE
+#define USING_NAMESPACE(ns) using namespace ns;
+#endif
+
+#ifndef DEFAULT
+#define DEFAULT(x)  = x
+#endif
+
+#ifndef ENUM
+#define ENUM(e)     enum e
+#endif
+
+#ifndef STRUCT
+#define STRUCT(s)   struct s
+#endif
+
+#else
+
+#define EXTERN_C    extern
+#define BEGIN_EXTERN_C
+#define END_EXTERN_C
+
+#define BEGIN_NAMESPACE(ns)
+#define END_NAMESPACE(ns)
+#define USING_NAMESPACE(ns)
+
+#ifndef DEFAULT
+#define DEFAULT(x)
+#endif
+
+#ifndef ENUM
+#define ENUM(e)\
+typedef enum e e;\
+enum e
+#endif
+
+#ifndef STRUCT
+#define STRUCT(s)\
+typedef struct s s;\
+struct s
+#endif
+
+#endif // __cplusplus
+
+#define BEGIN_NAMESPACE_HV  BEGIN_NAMESPACE(hv)
+#define END_NAMESPACE_HV    END_NAMESPACE(hv)
+#define USING_NAMESPACE_HV  USING_NAMESPACE(hv)
+
+#endif // HV_EXPORT_H_

+ 4 - 3
http/HttpMessage.h

@@ -4,6 +4,7 @@
 #include <string>
 #include <map>
 
+#include "hexport.h"
 #include "hstring.h"
 #include "httpdef.h"
 #include "http_content.h"
@@ -20,7 +21,7 @@ struct NetAddr {
     }
 };
 
-class HttpMessage {
+class HV_EXPORT HttpMessage {
 public:
     int                 type;
     unsigned short      http_major;
@@ -137,7 +138,7 @@ public:
 };
 
 #define DEFAULT_USER_AGENT "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
-class HttpRequest : public HttpMessage {
+class HV_EXPORT HttpRequest : public HttpMessage {
 public:
     http_method         method;
     // scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
@@ -189,7 +190,7 @@ public:
     void ParseUrl();
 };
 
-class HttpResponse : public HttpMessage {
+class HV_EXPORT HttpResponse : public HttpMessage {
 public:
     http_status         status_code;
 

+ 2 - 1
http/HttpParser.h

@@ -1,9 +1,10 @@
 #ifndef HTTP_PARSER_H_
 #define HTTP_PARSER_H_
 
+#include "hexport.h"
 #include "HttpMessage.h"
 
-class HttpParser {
+class HV_EXPORT HttpParser {
 public:
     http_version        version;
     http_session_type   type;

+ 11 - 10
http/client/http_client.h

@@ -1,6 +1,7 @@
 #ifndef HTTP_CLIENT_H_
 #define HTTP_CLIENT_H_
 
+#include "hexport.h"
 #include "HttpMessage.h"
 
 /*
@@ -28,20 +29,20 @@ int main(int argc, char* argv[]) {
 #define DEFAULT_HTTP_TIMEOUT    10 // s
 typedef struct http_client_s http_client_t;
 
-http_client_t* http_client_new(const char* host = NULL, int port = DEFAULT_HTTP_PORT, int tls = 0);
-int http_client_del(http_client_t* cli);
-const char* http_client_strerror(int errcode);
+HV_EXPORT http_client_t* http_client_new(const char* host = NULL, int port = DEFAULT_HTTP_PORT, int tls = 0);
+HV_EXPORT int http_client_del(http_client_t* cli);
+HV_EXPORT const char* http_client_strerror(int errcode);
 
-int http_client_set_timeout(http_client_t* cli, int timeout);
+HV_EXPORT int http_client_set_timeout(http_client_t* cli, int timeout);
 
-int http_client_clear_headers(http_client_t* cli);
-int http_client_set_header(http_client_t* cli, const char* key, const char* value);
-int http_client_del_header(http_client_t* cli, const char* key);
-const char* http_client_get_header(http_client_t* cli, const char* key);
+HV_EXPORT int http_client_clear_headers(http_client_t* cli);
+HV_EXPORT int http_client_set_header(http_client_t* cli, const char* key, const char* value);
+HV_EXPORT int http_client_del_header(http_client_t* cli, const char* key);
+HV_EXPORT const char* http_client_get_header(http_client_t* cli, const char* key);
 
-int http_client_send(http_client_t* cli, HttpRequest* req, HttpResponse* res);
+HV_EXPORT int http_client_send(http_client_t* cli, HttpRequest* req, HttpResponse* res);
 
 // http_client_new -> http_client_send -> http_client_del
-int http_client_send(HttpRequest* req, HttpResponse* res, int timeout = DEFAULT_HTTP_TIMEOUT);
+HV_EXPORT int http_client_send(HttpRequest* req, HttpResponse* res, int timeout = DEFAULT_HTTP_TIMEOUT);
 
 #endif  // HTTP_CLIENT_H_

+ 7 - 6
http/http_content.h

@@ -1,12 +1,13 @@
 #ifndef HTTP_CONTENT_H_
 #define HTTP_CONTENT_H_
 
+#include "hexport.h"
 #include "hstring.h"
 
 // QueryParams
 typedef hv::KeyValue    QueryParams;
-std::string dump_query_params(QueryParams& query_params);
-int         parse_query_params(const char* query_string, QueryParams& query_params);
+HV_EXPORT std::string dump_query_params(QueryParams& query_params);
+HV_EXPORT int         parse_query_params(const char* query_string, QueryParams& query_params);
 
 // NOTE: WITHOUT_HTTP_CONTENT
 // ndk-r10e no std::to_string and can't compile modern json.hpp
@@ -47,16 +48,16 @@ struct FormData {
 // name => FormData
 typedef HV_MAP<std::string, FormData>          MultiPart;
 #define DEFAULT_MULTIPART_BOUNDARY  "----WebKitFormBoundary7MA4YWxkTrZu0gW"
-std::string dump_multipart(MultiPart& mp, const char* boundary = DEFAULT_MULTIPART_BOUNDARY);
-int         parse_multipart(std::string& str, MultiPart& mp, const char* boundary);
+HV_EXPORT std::string dump_multipart(MultiPart& mp, const char* boundary = DEFAULT_MULTIPART_BOUNDARY);
+HV_EXPORT int         parse_multipart(std::string& str, MultiPart& mp, const char* boundary);
 
 // Json
 // https://github.com/nlohmann/json
 #include "json.hpp"
 using Json = nlohmann::json;
 extern std::string g_parse_json_errmsg;
-std::string dump_json(Json& json);
-int         parse_json(const char* str, Json& json, std::string& errmsg = g_parse_json_errmsg);
+HV_EXPORT std::string dump_json(Json& json);
+HV_EXPORT int         parse_json(const char* str, Json& json, std::string& errmsg = g_parse_json_errmsg);
 #endif
 
 #endif // HTTP_CONTENT_H_

+ 13 - 15
http/httpdef.h

@@ -1,9 +1,7 @@
 #ifndef HTTP_DEF_H_
 #define HTTP_DEF_H_
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "hexport.h"
 
 #define DEFAULT_HTTP_PORT       80
 #define DEFAULT_HTTPS_PORT      443
@@ -167,20 +165,20 @@ enum http_content_type {
 #undef XX
 };
 
-const char* http_status_str(enum http_status status);
-const char* http_method_str(enum http_method method);
-const char* http_content_type_str(enum http_content_type type);
+BEGIN_EXTERN_C
 
-enum http_status http_status_enum(const char* str);
-enum http_method http_method_enum(const char* str);
-enum http_content_type http_content_type_enum(const char* str);
+HV_EXPORT const char* http_status_str(enum http_status status);
+HV_EXPORT const char* http_method_str(enum http_method method);
+HV_EXPORT const char* http_content_type_str(enum http_content_type type);
 
-const char* http_content_type_suffix(enum http_content_type type);
-const char* http_content_type_str_by_suffix(const char* suffix);
-enum http_content_type http_content_type_enum_by_suffix(const char* suffix);
+HV_EXPORT enum http_status http_status_enum(const char* str);
+HV_EXPORT enum http_method http_method_enum(const char* str);
+HV_EXPORT enum http_content_type http_content_type_enum(const char* str);
 
-#ifdef __cplusplus
-}
-#endif
+HV_EXPORT const char* http_content_type_suffix(enum http_content_type type);
+HV_EXPORT const char* http_content_type_str_by_suffix(const char* suffix);
+HV_EXPORT enum http_content_type http_content_type_enum_by_suffix(const char* suffix);
+
+END_EXTERN_C
 
 #endif // HTTP_DEF_H_

+ 3 - 2
http/server/HttpServer.h

@@ -1,6 +1,7 @@
 #ifndef HTTP_SERVER_H_
 #define HTTP_SERVER_H_
 
+#include "hexport.h"
 #include "HttpService.h"
 
 typedef struct http_server_s {
@@ -53,9 +54,9 @@ int main() {
     return 0;
 }
  */
-int http_server_run(http_server_t* server, int wait = 1);
+HV_EXPORT int http_server_run(http_server_t* server, int wait = 1);
 
 // just for worker_processes = 0
-int http_server_stop(http_server_t* server);
+HV_EXPORT int http_server_stop(http_server_t* server);
 
 #endif

+ 2 - 1
http/server/HttpService.h

@@ -7,6 +7,7 @@
 #include <list>
 #include <memory>
 
+#include "hexport.h"
 #include "HttpMessage.h"
 
 #define DEFAULT_BASE_URL        "/v1/api"
@@ -34,7 +35,7 @@ typedef std::list<http_method_handler> http_method_handlers;
 // path => http_method_handlers
 typedef std::map<std::string, std::shared_ptr<http_method_handlers>> http_api_handlers;
 
-struct HttpService {
+struct HV_EXPORT HttpService {
     // preprocessor -> api -> web -> postprocessor
     http_api_handler    preprocessor;
     http_api_handler    postprocessor;

+ 1 - 0
hv.h

@@ -7,6 +7,7 @@
 
 // platform
 #include "hconfig.h"
+#include "hexport.h"
 #include "hplatform.h"
 
 // c

+ 2 - 0
protocol/dns.c

@@ -1,4 +1,6 @@
 #include "dns.h"
+
+#include "hdef.h"
 #include "hsocket.h"
 #include "herr.h"
 

+ 14 - 17
protocol/dns.h

@@ -1,11 +1,8 @@
 #ifndef HV_DNS_H_
 #define HV_DNS_H_
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "hdef.h"
+#include "hexport.h"
+#include "hplatform.h"
 
 #define DNS_PORT        53
 
@@ -82,27 +79,27 @@ typedef struct dns_s {
     dns_rr_t*       addtionals;
 } dns_t;
 
+BEGIN_EXTERN_C
+
 // www.example.com => 3www7example3com
-int dns_name_encode(const char* domain, char* buf);
+HV_EXPORT int dns_name_encode(const char* domain, char* buf);
 // 3www7example3com => www.example.com
-int dns_name_decode(const char* buf, char* domain);
+HV_EXPORT int dns_name_decode(const char* buf, char* domain);
 
-int dns_rr_pack(dns_rr_t* rr, char* buf, int len);
-int dns_rr_unpack(char* buf, int len, dns_rr_t* rr, int is_question);
+HV_EXPORT int dns_rr_pack(dns_rr_t* rr, char* buf, int len);
+HV_EXPORT int dns_rr_unpack(char* buf, int len, dns_rr_t* rr, int is_question);
 
-int dns_pack(dns_t* dns, char* buf, int len);
-int dns_unpack(char* buf, int len, dns_t* dns);
+HV_EXPORT int dns_pack(dns_t* dns, char* buf, int len);
+HV_EXPORT int dns_unpack(char* buf, int len, dns_t* dns);
 // NOTE: free dns->rrs
-void dns_free(dns_t* dns);
+HV_EXPORT void dns_free(dns_t* dns);
 
 // dns_pack -> sendto -> recvfrom -> dns_unpack
-int dns_query(dns_t* query, dns_t* response, const char* nameserver DEFAULT("127.0.1,1"));
+HV_EXPORT int dns_query(dns_t* query, dns_t* response, const char* nameserver DEFAULT("127.0.1,1"));
 
 // domain -> dns_t query; -> dns_query -> dns_t response; -> addrs
-int nslookup(const char* domain, uint32_t* addrs, int naddr, const char* nameserver DEFAULT("127.0.1.1"));
+HV_EXPORT int nslookup(const char* domain, uint32_t* addrs, int naddr, const char* nameserver DEFAULT("127.0.1.1"));
 
-#ifdef __cplusplus
-}
-#endif
+END_EXTERN_C
 
 #endif // HV_DNS_H_

+ 13 - 15
protocol/ftp.h

@@ -1,9 +1,7 @@
 #ifndef HV_FTP_H_
 #define HV_FTP_H_
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "hexport.h"
 
 #define FTP_COMMAND_PORT    21
 #define FTP_DATA_PORT       20
@@ -74,25 +72,25 @@ typedef struct ftp_handle_s {
     void*   userdata;
 } ftp_handle_t;
 
-const char* ftp_command_str(enum ftp_command cmd);
-const char* ftp_status_str(enum ftp_status status);
+BEGIN_EXTERN_C
 
-int ftp_connect(ftp_handle_t* hftp, const char* host, int port);
-int ftp_login(ftp_handle_t* hftp, const char* username, const char* password);
-int ftp_quit(ftp_handle_t* hftp);
+HV_EXPORT const char* ftp_command_str(enum ftp_command cmd);
+HV_EXPORT const char* ftp_status_str(enum ftp_status status);
 
-int ftp_exec(ftp_handle_t* hftp, const char* cmd, const char* param);
+HV_EXPORT int ftp_connect(ftp_handle_t* hftp, const char* host, int port);
+HV_EXPORT int ftp_login(ftp_handle_t* hftp, const char* username, const char* password);
+HV_EXPORT int ftp_quit(ftp_handle_t* hftp);
+
+HV_EXPORT int ftp_exec(ftp_handle_t* hftp, const char* cmd, const char* param);
 
 // local => remote
-int ftp_upload(ftp_handle_t* hftp, const char* local_filepath, const char* remote_filepath);
+HV_EXPORT int ftp_upload(ftp_handle_t* hftp, const char* local_filepath, const char* remote_filepath);
 // remote => local
-int ftp_download(ftp_handle_t* hftp, const char* remote_filepath, const char* local_filepath);
+HV_EXPORT int ftp_download(ftp_handle_t* hftp, const char* remote_filepath, const char* local_filepath);
 
 typedef int (*ftp_download_cb)(ftp_handle_t* hftp, char* buf, int len);
-int ftp_download_with_cb(ftp_handle_t* hftp, const char* filepath, ftp_download_cb cb);
+HV_EXPORT int ftp_download_with_cb(ftp_handle_t* hftp, const char* filepath, ftp_download_cb cb);
 
-#ifdef __cplusplus
-}
-#endif
+END_EXTERN_C
 
 #endif // HV_FTP_H_

+ 1 - 0
protocol/icmp.c

@@ -1,6 +1,7 @@
 #include "icmp.h"
 
 #include "netinet.h"
+#include "hdef.h"
 #include "hsocket.h"
 #include "htime.h"
 

+ 3 - 7
protocol/icmp.h

@@ -1,19 +1,15 @@
 #ifndef HV_ICMP_H_
 #define HV_ICMP_H_
 
-#include "hdef.h"
+#include "hexport.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+BEGIN_EXTERN_C
 
 // @param cnt: ping count
 // @return: ok count
 // @note: printd $CC -DPRINT_DEBUG
 int ping(const char* host, int cnt DEFAULT(4));
 
-#ifdef __cplusplus
-}
-#endif
+END_EXTERN_C
 
 #endif // HV_ICMP_H_

+ 11 - 13
protocol/smtp.h

@@ -1,9 +1,7 @@
 #ifndef HV_SMTP_H_
 #define HV_SMTP_H_
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "hexport.h"
 
 #define SMTP_PORT       25
 #define SMTPS_PORT      465
@@ -57,20 +55,20 @@ typedef struct mail_s {
     char* body;
 } mail_t;
 
-const char* smtp_command_str(enum smtp_command cmd);
-const char* smtp_status_str(enum smtp_status status);
+BEGIN_EXTERN_C
+
+HV_EXPORT const char* smtp_command_str(enum smtp_command cmd);
+HV_EXPORT const char* smtp_status_str(enum smtp_status status);
 
 // cmd param\r\n
-int smtp_build_command(enum smtp_command cmd, const char* param, char* buf, int buflen);
+HV_EXPORT int smtp_build_command(enum smtp_command cmd, const char* param, char* buf, int buflen);
 // status_code status_message\r\n
 
-int sendmail(const char* smtp_server,
-             const char* username,
-             const char* password,
-             mail_t* mail);
+HV_EXPORT int sendmail(const char* smtp_server,
+                       const char* username,
+                       const char* password,
+                       mail_t* mail);
 
-#ifdef __cplusplus
-}
-#endif
+END_EXTERN_C
 
 #endif // HV_SMTP_H_

+ 6 - 8
utils/base64.h

@@ -1,20 +1,18 @@
 #ifndef __BASE64_H__
 #define __BASE64_H__
 
+#include "hexport.h"
+
 enum {BASE64_OK = 0, BASE64_INVALID};
 
 #define BASE64_ENCODE_OUT_SIZE(s)   (((s) + 2) / 3 * 4)
 #define BASE64_DECODE_OUT_SIZE(s)   (((s)) / 4 * 3)
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+BEGIN_EXTERN_C
 
-int base64_encode(const unsigned char *in, unsigned int inlen, char *out);
-int base64_decode(const char *in, unsigned int inlen, unsigned char *out);
+HV_EXPORT int base64_encode(const unsigned char *in, unsigned int inlen, char *out);
+HV_EXPORT int base64_decode(const char *in, unsigned int inlen, unsigned char *out);
 
-#ifdef __cplusplus
-} // extern "C"
-#endif
+END_EXTERN_C
 
 #endif // __BASE64_H__

+ 4 - 0
utils/iniparser.cpp

@@ -27,6 +27,10 @@ int IniParser::Unload() {
     return 0;
 }
 
+int IniParser::Reload() {
+    return LoadFromFile(_filepath.c_str());
+}
+
 int IniParser::LoadFromFile(const char* filepath) {
     _filepath = filepath;
 

+ 10 - 10
utils/iniparser.h

@@ -5,6 +5,8 @@
 #include <string>
 using std::string;
 
+#include "hexport.h"
+
 #define DEFAULT_INI_COMMENT "#"
 #define DEFAULT_INI_DELIM   "="
 
@@ -18,7 +20,7 @@ key = value # span
 # div
 ***********************************/
 
-class IniNode {
+class HV_EXPORT IniNode {
 public:
     enum Type {
         INI_NODE_TYPE_UNKNOWN,
@@ -65,7 +67,7 @@ public:
     }
 };
 
-class IniSection : public IniNode {
+class HV_EXPORT IniSection : public IniNode {
 public:
     IniSection() : IniNode(), section(label) {
         type = INI_NODE_TYPE_SECTION;
@@ -73,7 +75,7 @@ public:
     string &section;
 };
 
-class IniKeyValue : public IniNode {
+class HV_EXPORT IniKeyValue : public IniNode {
 public:
     IniKeyValue() : IniNode(), key(label) {
         type = INI_NODE_TYPE_KEY_VALUE;
@@ -81,24 +83,22 @@ public:
     string &key;
 };
 
-class IniComment : public IniNode {
+class HV_EXPORT IniComment : public IniNode {
 public:
     IniComment() : IniNode(), comment(label) {
     }
     string &comment;
 };
 
-class IniParser {
+class HV_EXPORT IniParser {
 public:
     IniParser();
     ~IniParser();
 
-    void SetIniComment(const string& comment) {_comment = comment;}
-    void SetIniDilim(const string& delim) {_delim = delim;}
-
     int LoadFromFile(const char* filepath);
     int LoadFromMem(const char* data);
     int Unload();
+    int Reload();
 
     void DumpString(IniNode* pNode, string& str);
     string DumpString();
@@ -116,11 +116,11 @@ public:
     template<typename T>
     void Set(const string& key, const T& value, const string& section = "");
 
-private:
+public:
     string  _comment;
     string  _delim;
     string  _filepath;
-
+private:
     IniNode* root_;
 };
 

+ 7 - 9
utils/md5.h

@@ -25,6 +25,8 @@ documentation and/or software.
 #ifndef __MD5_H__
 #define __MD5_H__
 
+#include "hexport.h"
+
 /* POINTER defines a generic pointer type */
 typedef unsigned char *POINTER;
 
@@ -41,16 +43,12 @@ typedef struct {
   unsigned char buffer[64];                         /* input buffer */
 } MD5_CTX;
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+BEGIN_EXTERN_C
 
-void MD5Init(MD5_CTX *);
-void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
-void MD5Final(unsigned char [16], MD5_CTX *);
+HV_EXPORT void MD5Init(MD5_CTX *);
+HV_EXPORT void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
+HV_EXPORT void MD5Final(unsigned char [16], MD5_CTX *);
 
-#ifdef __cplusplus
-}
-#endif
+END_EXTERN_C
 
 #endif // __MD5_H__