This is an automated email from the ASF dual-hosted git repository.

colinlee pushed a commit to branch fix/win-vs-compilation
in repository https://gitbox.apache.org/repos/asf/tsfile.git

commit 4476eeb2b08409eaa0715d62a066de40c06cc92e
Author: 761417898 <[email protected]>
AuthorDate: Fri Oct 24 10:07:51 2025 +0800

    tsfile win-vs compilation
---
 cpp/CMakeLists.txt                                 | 47 +++++++++--
 cpp/examples/CMakeLists.txt                        |  4 +-
 cpp/examples/examples.cc                           |  2 +-
 cpp/src/CMakeLists.txt                             |  7 +-
 cpp/src/common/allocator/alloc_base.h              | 14 +++-
 cpp/src/common/container/blocking_queue.cc         | 57 --------------
 cpp/src/common/container/blocking_queue.h          | 44 -----------
 cpp/src/common/global.cc                           |  7 ++
 cpp/src/common/global.h                            |  2 +-
 cpp/src/common/mutex/mutex.h                       | 46 ++++-------
 cpp/src/cwrapper/tsfile_cwrapper.cc                |  9 ++-
 cpp/src/file/read_file.cc                          |  7 +-
 cpp/src/file/write_file.cc                         |  9 ---
 cpp/src/file/write_file.h                          | 48 ++++++-----
 cpp/src/utils/db_utils.h                           | 11 +--
 cpp/src/utils/util_define.h                        | 92 ++++++++++++++--------
 cpp/src/writer/tsfile_writer.cc                    |  6 +-
 cpp/src/writer/tsfile_writer.h                     | 14 +++-
 cpp/src/writer/value_page_writer.cc                |  4 +-
 cpp/src/writer/value_page_writer.h                 |  4 +-
 cpp/test/CMakeLists.txt                            | 28 +++++--
 cpp/test/cwrapper/c_release_test.cc                | 57 ++++----------
 cpp/test/cwrapper/cwrapper_test.cc                 |  1 -
 .../antlr4-cpp-runtime-4/CMakeLists.txt            |  2 +-
 .../runtime/src/Vocabulary.cpp                     |  2 +-
 25 files changed, 239 insertions(+), 285 deletions(-)

diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index 51f69e83..f1fdf017 100755
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -21,13 +21,20 @@ project(TsFile_CPP)
 
 cmake_policy(SET CMP0079 NEW)
 set(TsFile_CPP_VERSION 2.2.0.dev)
+
+# 统一 C++11 设置,避免 MSVC 下 -std=c++11 报错
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+
 set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -Wall")
 if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused -Wuninitialized 
-D__STDC_FORMAT_MACROS")
 endif ()
 
 message("cmake using: USE_CPP11=${USE_CPP11}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+# ✅ 去掉这里的 -std=c++11,交给 CMAKE_CXX_STANDARD 管理
+#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
 
 if (DEFINED ENV{CXX})
     set(CMAKE_CXX_COMPILER $ENV{CXX})
@@ -50,7 +57,6 @@ if (${COV_ENABLED})
     message("add_definitions -DCOV_ENABLED=1")
 endif ()
 
-
 if (NOT CMAKE_BUILD_TYPE)
     set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." 
FORCE)
 endif ()
@@ -88,7 +94,6 @@ if (NOT WIN32)
     endif ()
 endif ()
 
-
 # All libs will be stored here, including libtsfile, compress-encoding lib.
 set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
 
@@ -101,14 +106,44 @@ set(LIBRARY_INCLUDE_DIR ${PROJECT_BINARY_DIR}/include 
CACHE STRING "TsFile inclu
 set(THIRD_PARTY_INCLUDE ${PROJECT_BINARY_DIR}/third_party)
 
 set(SAVED_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
-set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -Wall -std=c++11")
+set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -Wall")
+
+if (MSVC)
+    # 推荐:使用动态 CRT (/MD). 可改为 "MultiThreaded" 来使用 /MT
+    set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL" CACHE STRING "MSVC 
runtime library" FORCE)
+    #set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")  # /MT 静态 CRT
+
+    set(WITH_STATIC_CRT OFF CACHE BOOL "Disable static CRT for antlr runtime" 
FORCE)
+endif()
+
 add_subdirectory(third_party)
 set(CMAKE_CXX_FLAGS "${SAVED_CXX_FLAGS}")
 
+if(MSVC)
+    # 保留你原来的所有忽略警告配置
+    add_compile_options(/wd4710)
+    add_compile_options(/wd5045)
+    add_compile_options(/wd4577)
+    add_compile_options(/wd4711)
+    add_compile_options(/wd4365)
+    add_compile_options(/wd5999)
+    add_compile_options(/wd4365)
+    add_compile_options(/W3)
+
+    # 增加必要的 MSVC 编译选项
+    add_compile_options(
+            /std:c++11
+            /utf-8
+            /W3
+            /wd4267  # 禁用 size_t 转换警告
+            /wd4996  # 禁用 POSIX 函数弃用警告
+            /wd4819  # 禁用编码警告
+    )
+endif()
+
 add_subdirectory(src)
 add_subdirectory(test)
 add_subdirectory(examples)
 if (TESTS_ENABLED)
     add_dependencies(TsFile_Test tsfile)
-endif ()
-
+endif ()
\ No newline at end of file
diff --git a/cpp/examples/CMakeLists.txt b/cpp/examples/CMakeLists.txt
index ebe6c66c..5b597043 100644
--- a/cpp/examples/CMakeLists.txt
+++ b/cpp/examples/CMakeLists.txt
@@ -27,10 +27,10 @@ set(SDK_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/../src/)
 message("SDK_INCLUDE_DIR: ${SDK_INCLUDE_DIR}")
 
 # TsFile shared object dir
-set(SDK_LIB_DIR_RELEASE ${PROJECT_SOURCE_DIR}/../build/Release/lib)
+set(SDK_LIB_DIR_RELEASE 
${PROJECT_SOURCE_DIR}/../cmake-build-release-visual-studio/lib)
 message("SDK_LIB_DIR_RELEASE: ${SDK_LIB_DIR_RELEASE}")
 
-set(SDK_LIB_DIR_DEBUG ${PROJECT_SOURCE_DIR}/../build/Debug/lib)
+set(SDK_LIB_DIR_DEBUG 
${PROJECT_SOURCE_DIR}/../cmake-build-release-visual-studio/lib)
 message("SDK_LIB_DIR_DEBUG: ${SDK_LIB_DIR_DEBUG}")
 
include_directories(${PROJECT_SOURCE_DIR}/../third_party/antlr4-cpp-runtime-4/runtime/src)
 
diff --git a/cpp/examples/examples.cc b/cpp/examples/examples.cc
index edbd819a..9c857c10 100644
--- a/cpp/examples/examples.cc
+++ b/cpp/examples/examples.cc
@@ -22,7 +22,7 @@
 
 int main() {
     // C++ examples
-    // std::cout << "begin write and read tsfile by cpp" << std::endl;
+    std::cout << "begin write and read tsfile by cpp" << std::endl;
     demo_write();
     demo_read();
     std::cout << "begin write and read tsfile by c" << std::endl;
diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt
index 86c67f2b..50527b2e 100644
--- a/cpp/src/CMakeLists.txt
+++ b/cpp/src/CMakeLists.txt
@@ -31,7 +31,7 @@ if (${COV_ENABLED})
 endif ()
 add_definitions(-DANTLR4CPP_STATIC)
 set(ANTLR4_WITH_STATIC_CRT OFF)
-
+add_definitions(-DTSFILE_EXPORTS)
 
 set(PROJECT_INCLUDE_DIR
         ${CMAKE_SOURCE_DIR}/src
@@ -72,6 +72,11 @@ else()
     target_link_libraries(tsfile common_obj compress_obj cwrapper_obj file_obj 
read_obj write_obj parser_obj)
 endif()
 
+# ✅ MSVC 下自动导出所有符号,生成 .lib
+if(MSVC)
+    set_target_properties(tsfile PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
+endif()
+
 # to trigger copy headers
 add_dependencies(tsfile utils_obj encoding_obj)
 
diff --git a/cpp/src/common/allocator/alloc_base.h 
b/cpp/src/common/allocator/alloc_base.h
index e9824b11..e134d496 100644
--- a/cpp/src/common/allocator/alloc_base.h
+++ b/cpp/src/common/allocator/alloc_base.h
@@ -26,6 +26,16 @@
 
 #include "utils/util_define.h"
 
+#ifdef _WIN32
+    #ifdef TSFILE_EXPORTS
+        #define TSFILE_API __declspec(dllexport)
+    #else
+        #define TSFILE_API __declspec(dllimport)
+    #endif
+#else
+    #define TSFILE_API
+#endif
+
 namespace common {
 
 enum AllocModID {
@@ -117,7 +127,7 @@ class ModStat {
     static const int32_t ITEM_COUNT = __LAST_MOD_ID;
     int32_t *stat_arr_;
 
-    STATIC_ASSERT((ITEM_SIZE % sizeof(int32_t) == 0), ModStat_ITEM_SIZE_ERROR);
+    static_assert(ITEM_SIZE % sizeof(int32_t) == 0, "ITEM_SIZE must be a 
multiple of sizeof(int32_t)");
 };
 
 /* base allocator */
@@ -127,7 +137,7 @@ class BaseAllocator {
     void free(void *ptr) { mem_free(ptr); }
 };
 
-extern BaseAllocator g_base_allocator;
+TSFILE_API extern BaseAllocator g_base_allocator;
 
 }  // end namespace common
 
diff --git a/cpp/src/common/container/blocking_queue.cc 
b/cpp/src/common/container/blocking_queue.cc
deleted file mode 100644
index f5123d32..00000000
--- a/cpp/src/common/container/blocking_queue.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * License); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "blocking_queue.h"
-
-namespace common {
-
-BlockingQueue::BlockingQueue() : queue_(), mutex_(), cond_() {
-    pthread_mutex_init(&mutex_, NULL);
-    pthread_cond_init(&cond_, NULL);
-}
-
-BlockingQueue::~BlockingQueue() {
-    pthread_mutex_destroy(&mutex_);
-    pthread_cond_destroy(&cond_);
-}
-
-void BlockingQueue::push(void *data) {
-    pthread_mutex_lock(&mutex_);
-    queue_.push(data);
-    pthread_mutex_unlock(&mutex_);
-    /*
-     * it is safe to signal after unlock.
-     * since pthread_cond_wait is guarantee to unlock and sleep atomically.
-     */
-    pthread_cond_signal(&cond_);
-}
-
-void *BlockingQueue::pop() {
-    void *ret_data = NULL;
-    pthread_mutex_lock(&mutex_);
-    while (queue_.empty()) {
-        pthread_cond_wait(&cond_, &mutex_);
-    }
-    ret_data = queue_.front();
-    queue_.pop();
-    pthread_mutex_unlock(&mutex_);
-    return ret_data;
-}
-
-}  // end namespace common
\ No newline at end of file
diff --git a/cpp/src/common/container/blocking_queue.h 
b/cpp/src/common/container/blocking_queue.h
deleted file mode 100644
index e03ea3a4..00000000
--- a/cpp/src/common/container/blocking_queue.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * License); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-#ifndef COMMON_CONTAINER_BLOCKING_QUEUE_H
-#define COMMON_CONTAINER_BLOCKING_QUEUE_H
-
-#include <pthread.h>
-
-#include <queue>
-
-namespace common {
-
-class BlockingQueue {
-   public:
-    BlockingQueue();
-    ~BlockingQueue();
-
-    void push(void* data);
-    // if empty, blocking
-    void* pop();
-
-   private:
-    std::queue<void*> queue_;
-    pthread_mutex_t mutex_;
-    pthread_cond_t cond_;
-};
-
-}  // end namespace common
-#endif  // COMMON_CONTAINER_BLOCKING_QUEUE_H
diff --git a/cpp/src/common/global.cc b/cpp/src/common/global.cc
index 21b3dad7..6b1180b3 100644
--- a/cpp/src/common/global.cc
+++ b/cpp/src/common/global.cc
@@ -121,6 +121,13 @@ int init_common() {
 bool is_timestamp_column_name(const char* time_col_name) {
     // both "time" and "timestamp" refer to timestmap column.
     int32_t len = strlen(time_col_name);
+#ifdef _WIN32
+#include <string.h>
+#define strncasecmp _strnicmp
+#else
+#include <strings.h>
+#endif
+
     if (len == 4) {
         return strncasecmp(time_col_name, "time", 4) == 0;
     } else if (len == 9) {
diff --git a/cpp/src/common/global.h b/cpp/src/common/global.h
index 564f30c6..a540ef75 100644
--- a/cpp/src/common/global.h
+++ b/cpp/src/common/global.h
@@ -26,7 +26,7 @@
 #include "common/config/config.h"
 namespace common {
 
-extern ConfigValue g_config_value_;
+TSFILE_API extern ConfigValue g_config_value_;
 extern ColumnSchema g_time_column_schema;
 
 FORCE_INLINE int set_global_time_data_type(uint8_t data_type) {
diff --git a/cpp/src/common/mutex/mutex.h b/cpp/src/common/mutex/mutex.h
index 8409e159..1c5ec18a 100644
--- a/cpp/src/common/mutex/mutex.h
+++ b/cpp/src/common/mutex/mutex.h
@@ -20,56 +20,44 @@
 #ifndef COMMON_MUTEX_MUTEX_H
 #define COMMON_MUTEX_MUTEX_H
 
-#include <errno.h>
-#include <pthread.h>
-
+#include <mutex>
 #include "utils/util_define.h"
 
 namespace common {
 
 class Mutex {
-   public:
-    Mutex() : mutex_() { pthread_mutex_init(&mutex_, NULL); }
-    ~Mutex() { pthread_mutex_destroy(&mutex_); }
+public:
+    Mutex() = default;
+    ~Mutex() = default;
 
     void lock() {
-        int ret = EBUSY;
-        do {
-            ret = pthread_mutex_lock(&mutex_);
-        } while (UNLIKELY(ret == EBUSY || ret == EAGAIN));
-        ASSERT(ret == 0);
+        mutex_.lock();
     }
 
     void unlock() {
-        int ret = pthread_mutex_unlock(&mutex_);
-        ASSERT(ret == 0);
-        (void)ret;
+        mutex_.unlock();
     }
 
     bool try_lock() {
-        int ret = pthread_mutex_trylock(&mutex_);
-        if (ret == 0) {
-            return true;
-        } else if (ret == EBUSY || ret == EAGAIN) {
-            return false;
-        } else {
-            ASSERT(false);
-            return false;
-        }
+        return mutex_.try_lock();
     }
 
-   private:
-    pthread_mutex_t mutex_;
+private:
+    std::mutex mutex_;
 };
 
 class MutexGuard {
-   public:
-    MutexGuard(Mutex &m) : m_(m) { m_.lock(); }
+public:
+    explicit MutexGuard(Mutex &m) : m_(m) { m_.lock(); }
     ~MutexGuard() { m_.unlock(); }
 
-   private:
+    // Non-copyable
+    MutexGuard(const MutexGuard&) = delete;
+    MutexGuard& operator=(const MutexGuard&) = delete;
+
+private:
     Mutex &m_;
 };
 
 }  // end namespace common
-#endif  // COMMON_MUTEX_MUTEX_H
+#endif  // COMMON_MUTEX_MUTEX_H
\ No newline at end of file
diff --git a/cpp/src/cwrapper/tsfile_cwrapper.cc 
b/cpp/src/cwrapper/tsfile_cwrapper.cc
index e6e15dd4..eee1d81d 100644
--- a/cpp/src/cwrapper/tsfile_cwrapper.cc
+++ b/cpp/src/cwrapper/tsfile_cwrapper.cc
@@ -21,7 +21,6 @@
 
 #include <file/write_file.h>
 #include <reader/qds_without_timegenerator.h>
-#include <unistd.h>
 #include <writer/tsfile_table_writer.h>
 
 #include "common/tablet.h"
@@ -76,7 +75,13 @@ WriteFile write_file_new(const char *pathname, ERRNO 
*err_code) {
     int ret;
     init_tsfile_config();
 
-    if (access(pathname, F_OK) == 0) {
+    if (
+    #ifdef _WIN32
+        _access(pathname, 0)
+    #else
+        access(pathname, F_OK)
+    #endif
+        == 0) {
         *err_code = common::E_ALREADY_EXIST;
         return nullptr;
     }
diff --git a/cpp/src/file/read_file.cc b/cpp/src/file/read_file.cc
index cc08bf25..347c1e62 100644
--- a/cpp/src/file/read_file.cc
+++ b/cpp/src/file/read_file.cc
@@ -21,7 +21,6 @@
 
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <unistd.h>
 
 #include "common/logger/elog.h"
 #include "common/tsfile_common.h"
@@ -30,7 +29,7 @@
 #include <io.h>
 #include <windows.h>
 
-ssize_t pread(int fd, void *buf, size_t count, uint64_t offset);
+uint64_t pread(int fd, void *buf, size_t count, uint64_t offset);
 #endif
 
 using namespace common;
@@ -114,7 +113,7 @@ int ReadFile::read(int32_t offset, char *buf, int32_t 
buf_size,
     int ret = E_OK;
     read_len = 0;
     while (read_len < buf_size) {
-        ssize_t pread_size = ::pread(fd_, buf + read_len, buf_size - read_len,
+        uint64_t pread_size = ::pread(fd_, buf + read_len, buf_size - read_len,
                                      offset + read_len);
         if (pread_size < 0) {
             ret = E_FILE_READ_ERR;
@@ -133,7 +132,7 @@ int ReadFile::read(int32_t offset, char *buf, int32_t 
buf_size,
 }  // end namespace storage
 
 #ifdef _WIN32
-ssize_t pread(int fd, void *buf, size_t count, uint64_t offset) {
+uint64_t pread(int fd, void *buf, size_t count, uint64_t offset) {
     long unsigned int read_bytes = 0;
 
     OVERLAPPED overlapped;
diff --git a/cpp/src/file/write_file.cc b/cpp/src/file/write_file.cc
index c8c2cbba..d5883bc7 100644
--- a/cpp/src/file/write_file.cc
+++ b/cpp/src/file/write_file.cc
@@ -19,16 +19,7 @@
 
 #include "write_file.h"
 
-#include <errno.h>
 #include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-#include "common/config/config.h"
-#include "common/logger/elog.h"
 #include "utils/errno_define.h"
 
 #ifdef _WIN32
diff --git a/cpp/src/file/write_file.h b/cpp/src/file/write_file.h
index 3346d7ad..11607827 100644
--- a/cpp/src/file/write_file.h
+++ b/cpp/src/file/write_file.h
@@ -1,24 +1,5 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * License); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef FILE_WRITE_FILE_H
-#define FILE_WRITE_FILE_H
+#ifndef STORAGE_WRITE_FILE_H_
+#define STORAGE_WRITE_FILE_H_
 
 #include <string>
 
@@ -27,10 +8,25 @@
 #include "utils/storage_utils.h"
 #endif
 
+// Windows 兼容性处理
+#ifdef _WIN32
+#include <io.h>
+#include <fcntl.h>
+#define mode_t int
+#define S_IRUSR _S_IREAD
+#define S_IWUSR _S_IWRITE
+#define S_IRGRP 0
+#define S_IROTH 0
+#else
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
+
 namespace storage {
 
 class WriteFile {
-   public:
+public:
 #ifndef LIBTSFILE_SDK
     WriteFile() : path_(), file_id_(), fd_(-1) {}
     FORCE_INLINE common::FileID get_file_id() const { return file_id_; }
@@ -42,15 +38,14 @@ class WriteFile {
     int create(const std::string &file_name, int flags, mode_t mode);
     bool file_opened() const { return fd_ > 0; }
     int write(const char *buf, uint32_t len);
-    // int flush() { return common::E_OK; } // TODO
     int sync();
     int close();
     FORCE_INLINE std::string get_file_path() { return path_; }
 
-   private:
+private:
     int do_create(int flags, mode_t mode);
 
-   private:
+private:
     std::string path_;
 #ifndef LIBTSFILE_SDK
     common::FileID file_id_;
@@ -59,4 +54,5 @@ class WriteFile {
 };
 
 }  // end namespace storage
-#endif  // FILE_WRITE_FILE_H
+
+#endif  // STORAGE_WRITE_FILE_H_
\ No newline at end of file
diff --git a/cpp/src/utils/db_utils.h b/cpp/src/utils/db_utils.h
index 90d0b969..a2a7ec26 100644
--- a/cpp/src/utils/db_utils.h
+++ b/cpp/src/utils/db_utils.h
@@ -23,7 +23,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>  // memcpy
-#include <sys/time.h>
+#include <chrono>
 
 #include <iostream>
 #include <sstream>
@@ -308,12 +308,9 @@ struct ColumnSchema {
 };
 
 FORCE_INLINE int64_t get_cur_timestamp() {
-    int64_t timestamp = 0;
-    struct timeval tv;
-    if (gettimeofday(&tv, NULL) >= 0) {
-        timestamp = (int64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
-    }
-    return timestamp;
+    using namespace std::chrono;
+    auto now = system_clock::now();
+    return duration_cast<milliseconds>(now.time_since_epoch()).count();
 }
 
 #if 0
diff --git a/cpp/src/utils/util_define.h b/cpp/src/utils/util_define.h
index 9667de76..95232c95 100644
--- a/cpp/src/utils/util_define.h
+++ b/cpp/src/utils/util_define.h
@@ -23,80 +23,83 @@
 #include <stdint.h>
 #include <stdlib.h>
 
-/* ======== unsued ======== */
+/* ======== 跨平台兼容性定义 ======== */
+#if defined(_WIN32)
+#define PLATFORM_WINDOWS 1
+#elif defined(__APPLE__)
+#define PLATFORM_APPLE 1
+#elif defined(__linux__)
+#define PLATFORM_LINUX 1
+#else
+#define PLATFORM_UNKNOWN 1
+#endif
+
+/* ======== unused ======== */
 #define UNUSED(v) ((void)(v))
 
 /* ======== inline ======== */
-#ifdef __GNUC__
+#if defined(_MSC_VER)
+#define FORCE_INLINE __forceinline
+#elif defined(__GNUC__)
 #define FORCE_INLINE inline __attribute__((always_inline))
 #else
 #define FORCE_INLINE inline
-#endif  // __GNUC__
+#endif
 
 #ifdef BUILD_FOR_SMALL_BINARY
 #define INLINE FORCE_INLINE
 #else
 #define INLINE
-#endif  // BUILD_FOR_SMALL_BINARY
+#endif
 
-/* ======== likely ======== */
+/* ======== likely/unlikely ======== */
 #if defined(__GNUC__) && __GNUC__ >= 4
 #define LIKELY(x) (__builtin_expect((x), 1))
 #define UNLIKELY(x) (__builtin_expect((x), 0))
+#elif defined(_MSC_VER)
+#define LIKELY(x) (x)
+#define UNLIKELY(x) (x)
 #else
 #define LIKELY(x) (x)
 #define UNLIKELY(x) (x)
-#endif  // __GNUC__ >= 4
+#endif
 
 /* ======== nullptr ======== */
-#if __cplusplus < 201103L
+#if __cplusplus < 201103L && !defined(_MSC_VER)
 #ifndef nullptr
 #define nullptr NULL
 #endif
 #define OVERRIDE
 #else
 #define OVERRIDE override
-#endif  // __cplusplus < 201103L
+#endif
 
 /* ======== cache line ======== */
 #ifndef CACHE_LINE_SIZE
 #define CACHE_LINE_SIZE 64
-#endif  // CACHE_LINE_SIZE
+#endif
 
 /* ======== assert ======== */
 #ifdef NDEBUG
 #define ASSERT(condition) ((void)0)
 #else
 #define ASSERT(condition) assert((condition))
-#endif  // NDEBUG
+#endif
 
-/* ======== statis assert ======== */
-/*
- * To be compatible with C++ before C++11,
- * @msg should be a single word (use -/_ to concat)
- * such as This_should_be_TRUE
- */
-#if __cplusplus < 201103L
-// TODO only define this when DEBUG
+/* ======== static assert ======== */
+#if __cplusplus < 201103L && !defined(_MSC_VER)
 #define STATIC_ASSERT(cond, msg) \
     typedef char static_assertion_##msg[(cond) ? 1 : -1] 
__attribute__((unused))
 #else
 #define STATIC_ASSERT(cond, msg) static_assert((cond), #msg)
-#endif  // __cplusplus < 201103L
+#endif
 
-/* ======== atomic operation ======== */
+/* ======== atomic operations ======== */
+#if defined(__GNUC__) || defined(__clang__)
 #define ATOMIC_FAA(val_addr, addv) \
     __atomic_fetch_add((val_addr), (addv), __ATOMIC_SEQ_CST)
 #define ATOMIC_AAF(val_addr, addv) \
     __atomic_add_fetch((val_addr), (addv), __ATOMIC_SEQ_CST)
-/*
- * It implements an atomic compare and exchange operation.
- * This compares the contents of *ptr with the contents of *expected.
- * - If equal, the operation is a reader-modify-writer operation that writes
- * desired into *ptr.
- * - If they are not equal, the operation is a reader and the current contents
- * of *ptr are written into *expected
- */
 #define ATOMIC_CAS(val_addr, expected, desired)                            \
     __atomic_compare_exchange_n((val_addr), (expected), (desired),         \
                                 /* weak = */ false,                        \
@@ -105,14 +108,39 @@
 #define ATOMIC_LOAD(val_addr) __atomic_load_n((val_addr), __ATOMIC_SEQ_CST)
 #define ATOMIC_STORE(val_addr, val) \
     __atomic_store_n((val_addr), (val), __ATOMIC_SEQ_CST)
+#elif defined(_MSC_VER)
+#include <intrin.h>
+#define ATOMIC_FAA(val_addr, addv) _InterlockedExchangeAdd(val_addr, addv)
+#ifdef _WIN64
+#define ATOMIC_AAF(val_addr, addv) \
+(_InterlockedExchangeAdd64(reinterpret_cast<volatile __int64*>(val_addr), 
static_cast<__int64>(addv)) + (addv))
+#else
+#define ATOMIC_AAF(val_addr, addv) \
+(_InterlockedExchangeAdd(reinterpret_cast<volatile long*>(val_addr), 
static_cast<long>(addv)) + (addv))
+#endif
 
-/* ======== align ======== */
+#define ATOMIC_CAS(val_addr, expected, desired) \
+    (_InterlockedCompareExchange(val_addr, desired, *expected) == *expected)
+#define ATOMIC_LOAD(val_addr) (*val_addr)
+#define ATOMIC_STORE(val_addr, val) (*val_addr = val)
+#else
+#error "Atomic operations not supported on this platform"
+#endif
+
+/* ======== alignment ======== */
+#if defined(_MSC_VER)
+#define ALIGNED(a) __declspec(align(a))
+#elif defined(__GNUC__)
 #define ALIGNED(a) __attribute__((aligned(a)))
+#else
+#define ALIGNED(a)
+#endif
+
 #define ALIGNED_4 ALIGNED(4)
 #define ALIGNED_8 ALIGNED(8)
 
 /* ======== disallow copy and assign ======== */
-#if __cplusplus < 201103L
+#if __cplusplus < 201103L && !defined(_MSC_VER)
 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
     TypeName(const TypeName&);             \
     void operator=(const TypeName&)
@@ -126,7 +154,7 @@
 #define RET_FAIL(expr) UNLIKELY(common::E_OK != (ret = (expr)))
 #define RFAIL(expr) UNLIKELY(common::E_OK != (ret = (expr)))
 #define RET_SUCC(expr) LIKELY(common::E_OK == (ret = (expr)))
-#define RSUCC(expr) LIKELY(common::E_OK != (ret = (exprt)))
+#define RSUCC(expr) LIKELY(common::E_OK == (ret = (expr)))
 #define IS_SUCC(ret) LIKELY(common::E_OK == (ret))
 #define IS_FAIL(ret) UNLIKELY(common::E_OK != (ret))
 
@@ -142,4 +170,4 @@
  */
 #define INT64_TO_BASE10_MAX_LEN 24
 
-#endif  // UTILS_UTIL_DEFINE_H
+#endif  // UTILS_UTIL_DEFINE_H
\ No newline at end of file
diff --git a/cpp/src/writer/tsfile_writer.cc b/cpp/src/writer/tsfile_writer.cc
index 54c1be02..145d48cc 100644
--- a/cpp/src/writer/tsfile_writer.cc
+++ b/cpp/src/writer/tsfile_writer.cc
@@ -19,8 +19,6 @@
 
 #include "tsfile_writer.h"
 
-#include <unistd.h>
-
 #include "chunk_writer.h"
 #include "common/config/config.h"
 #include "file/tsfile_io_writer.h"
@@ -148,7 +146,11 @@ int TsFileWriter::register_table(
 }
 
 bool check_file_exist(const std::string &file_path) {
+#ifdef _WIN32
+    return _access(file_path.c_str(), 0) == 0;
+#else
     return access(file_path.c_str(), F_OK) == 0;
+#endif
 }
 
 int TsFileWriter::open(const std::string &file_path, int flags, mode_t mode) {
diff --git a/cpp/src/writer/tsfile_writer.h b/cpp/src/writer/tsfile_writer.h
index bad92381..8fa725b7 100644
--- a/cpp/src/writer/tsfile_writer.h
+++ b/cpp/src/writer/tsfile_writer.h
@@ -19,9 +19,17 @@
 #ifndef WRITER_TSFILE_WRITER_H
 #define WRITER_TSFILE_WRITER_H
 
-#include <fcntl.h>
-
-#include <climits>
+#ifdef _WIN32
+#include <io.h>
+#define mode_t int
+#define S_IRUSR _S_IREAD
+#define S_IWUSR _S_IWRITE
+#define S_IRGRP 0
+#define S_IROTH 0
+#else
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
 #include <map>
 #include <memory>
 #include <string>
diff --git a/cpp/src/writer/value_page_writer.cc 
b/cpp/src/writer/value_page_writer.cc
index b95307f7..38beb341 100644
--- a/cpp/src/writer/value_page_writer.cc
+++ b/cpp/src/writer/value_page_writer.cc
@@ -28,8 +28,6 @@ using namespace common;
 
 namespace storage {
 
-uint32_t ValuePageWriter::MASK = 1 << 7;
-
 int ValuePageData::init(ByteStream &col_notnull_bitmap_bs, ByteStream 
&value_bs,
                         Compressor *compressor, uint32_t size) {
     int ret = E_OK;
@@ -81,6 +79,8 @@ int ValuePageData::init(ByteStream &col_notnull_bitmap_bs, 
ByteStream &value_bs,
     return ret;
 }
 
+ValuePageWriter::~ValuePageWriter() { destroy(); }
+
 int ValuePageWriter::init(TSDataType data_type, TSEncoding encoding,
                           CompressionType compression) {
     int ret = E_OK;
diff --git a/cpp/src/writer/value_page_writer.h 
b/cpp/src/writer/value_page_writer.h
index 4cf2ffa9..6363b9bf 100644
--- a/cpp/src/writer/value_page_writer.h
+++ b/cpp/src/writer/value_page_writer.h
@@ -98,7 +98,7 @@ class ValuePageWriter {
           is_inited_(false),
           col_notnull_bitmap_(),
           size_(0) {}
-    ~ValuePageWriter() { destroy(); }
+    ~ValuePageWriter();
     int init(common::TSDataType data_type, common::TSEncoding encoding,
              common::CompressionType compression);
     void reset();
@@ -213,7 +213,7 @@ class ValuePageWriter {
     std::vector<uint8_t> col_notnull_bitmap_;
     uint32_t size_;
 
-    static uint32_t MASK;
+    const uint32_t MASK = 1 << 7;
 };
 
 }  // end namespace storage
diff --git a/cpp/test/CMakeLists.txt b/cpp/test/CMakeLists.txt
index 1beb310d..7f804822 100644
--- a/cpp/test/CMakeLists.txt
+++ b/cpp/test/CMakeLists.txt
@@ -106,8 +106,8 @@ if (${COV_ENABLED})
     add_compile_options(-fprofile-arcs -ftest-coverage)
 endif ()
 
-add_definitions(-DANTLR4CPP_STATIC)
-set(ANTLR4_WITH_STATIC_CRT OFF)
+#add_definitions(-DANTLR4CPP_STATIC)
+#set(ANTLR4_WITH_STATIC_CRT OFF)
 
 add_executable(TsFile_Test ${TEST_SRCS})
 target_link_libraries(
@@ -119,15 +119,27 @@ target_link_libraries(
 
 set_target_properties(TsFile_Test PROPERTIES RUNTIME_OUTPUT_DIRECTORY 
${LIB_TSFILE_SDK_DIR})
 
-if (WIN32)
+if(WIN32)
+    # 获取所有匹配的 DLL 文件
+    file(GLOB TSFILE_DLLS "${LIBRARY_OUTPUT_PATH}/*")
+
     add_custom_command(TARGET TsFile_Test POST_BUILD
-            COMMAND ${CMAKE_COMMAND} -E copy
-            "${LIBRARY_OUTPUT_PATH}/libtsfile.dll"
-            "$<TARGET_FILE_DIR:TsFile_Test>"
-            COMMENT "Copying libtsfile.dll to test executable directory"
+            COMMAND ${CMAKE_COMMAND} -E make_directory 
"$<TARGET_FILE_DIR:TsFile_Test>"
+            COMMENT "Copying all tsfile*.dll files to test executable 
directory"
             VERBATIM
     )
-endif ()
+
+    foreach(dll ${TSFILE_DLLS})
+        add_custom_command(TARGET TsFile_Test POST_BUILD
+                COMMAND ${CMAKE_COMMAND} -E copy_if_different
+                "${dll}"
+                "$<TARGET_FILE_DIR:TsFile_Test>"
+                VERBATIM
+        )
+    endforeach()
+endif()
+
+target_compile_definitions(TsFile_Test PRIVATE ANTLR4CPP_STATIC)
 
 include(GoogleTest)
 gtest_discover_tests(TsFile_Test)
diff --git a/cpp/test/cwrapper/c_release_test.cc 
b/cpp/test/cwrapper/c_release_test.cc
index 692f1043..d1472b29 100644
--- a/cpp/test/cwrapper/c_release_test.cc
+++ b/cpp/test/cwrapper/c_release_test.cc
@@ -18,7 +18,6 @@
  */
 
 #include <gtest/gtest.h>
-#include <unistd.h>
 #include <utils/db_utils.h>
 extern "C" {
 #include "cwrapper/errno_define_c.h"
@@ -92,13 +91,9 @@ TEST_F(CReleaseTest, TsFileWriterNew) {
     table_schema.column_schemas =
         static_cast<ColumnSchema *>(malloc(sizeof(ColumnSchema) * 2));
     table_schema.column_schemas[0] =
-        (ColumnSchema){.column_name = strdup("col1"),
-                       .data_type = TS_DATATYPE_STRING,
-                       .column_category = TAG};
+        ColumnSchema{strdup("col1"), TS_DATATYPE_STRING, TAG};
     table_schema.column_schemas[1] =
-        (ColumnSchema){.column_name = strdup("col2"),
-                       .data_type = TS_DATATYPE_INT32,
-                       .column_category = FIELD};
+        ColumnSchema{strdup("col2"), TS_DATATYPE_INT32, FIELD};
 
     writer = tsfile_writer_new(file, &table_schema, &error_code);
     ASSERT_EQ(RET_OK, error_code);
@@ -123,21 +118,15 @@ TEST_F(CReleaseTest, TsFileWriterWriteDataAbnormalColumn) 
{
     abnormal_schema.column_schemas =
         static_cast<ColumnSchema *>(malloc(sizeof(ColumnSchema) * 4));
     abnormal_schema.column_schemas[0] =
-        (ColumnSchema){.column_name = strdup("!@#$%^*()_+-="),
-                       .data_type = TS_DATATYPE_STRING,
-                       .column_category = TAG};
+        ColumnSchema{strdup("!@#$%^*()_+-="), TS_DATATYPE_STRING, TAG};
 
     // TAG's datatype is not correct
     abnormal_schema.column_schemas[1] =
-        (ColumnSchema){.column_name = strdup("TAG2"),
-                       .data_type = TS_DATATYPE_INT32,
-                       .column_category = TAG};
+        ColumnSchema{strdup("TAG2"), TS_DATATYPE_INT32, TAG};
 
     // same column name with column[0]
     abnormal_schema.column_schemas[2] =
-        (ColumnSchema){.column_name = strdup("!@#$%^*()_+-="),
-                       .data_type = TS_DATATYPE_DOUBLE,
-                       .column_category = FIELD};
+        ColumnSchema{strdup("!@#$%^*()_+-="), TS_DATATYPE_DOUBLE, FIELD};
 
     // column name conflict
     TsFileWriter writer =
@@ -146,9 +135,7 @@ TEST_F(CReleaseTest, TsFileWriterWriteDataAbnormalColumn) {
     free(abnormal_schema.column_schemas[2].column_name);
 
     abnormal_schema.column_schemas[2] =
-        (ColumnSchema){.column_name = strdup("!@#$%^*()_+-=1"),
-                       .data_type = TS_DATATYPE_DOUBLE,
-                       .column_category = FIELD};
+        ColumnSchema{strdup("!@#$%^*()_+-=1"), TS_DATATYPE_DOUBLE, FIELD};
 
     // datatype conflict
     writer = tsfile_writer_new(file, &abnormal_schema, &error_code);
@@ -156,9 +143,7 @@ TEST_F(CReleaseTest, TsFileWriterWriteDataAbnormalColumn) {
 
     free(abnormal_schema.column_schemas[1].column_name);
     abnormal_schema.column_schemas[1] =
-        (ColumnSchema){.column_name = strdup("TAG2"),
-                       .data_type = TS_DATATYPE_STRING,
-                       .column_category = TAG};
+        ColumnSchema{strdup("TAG2"), TS_DATATYPE_STRING, TAG};
 
     writer = tsfile_writer_new(file, &abnormal_schema, &error_code);
     ASSERT_EQ(RET_OK, error_code);
@@ -194,8 +179,8 @@ TEST_F(CReleaseTest, TsFileWriterWriteDataAbnormalColumn) {
            error_code == RET_OK) {
         Timestamp timestamp =
             tsfile_result_set_get_value_by_name_int64_t(result_set, "time");
-        ASSERT_EQ(timestamp * 100.0, 
tsfile_result_set_get_value_by_name_double(
-                                         result_set, "!@#$%^*()_+-=1"));
+        ASSERT_EQ(static_cast<double>(timestamp) * 100.0,
+                 tsfile_result_set_get_value_by_name_double(result_set, 
"!@#$%^*()_+-=1"));
         char *value_str =
             tsfile_result_set_get_value_by_index_string(result_set, 2);
         ASSERT_EQ("device1", std::string(value_str));
@@ -228,29 +213,17 @@ TEST_F(CReleaseTest, TsFileWriterMultiDataType) {
     all_type_schema.column_schemas =
         static_cast<ColumnSchema *>(malloc(sizeof(ColumnSchema) * 6));
     all_type_schema.column_schemas[0] =
-        (ColumnSchema){.column_name = strdup("TAG"),
-                       .data_type = TS_DATATYPE_STRING,
-                       .column_category = TAG};
+        ColumnSchema{strdup("TAG"), TS_DATATYPE_STRING, TAG};
     all_type_schema.column_schemas[1] =
-        (ColumnSchema){.column_name = strdup("INT32"),
-                       .data_type = TS_DATATYPE_INT32,
-                       .column_category = FIELD};
+        ColumnSchema{strdup("INT32"), TS_DATATYPE_INT32, FIELD};
     all_type_schema.column_schemas[2] =
-        (ColumnSchema){.column_name = strdup("INT64"),
-                       .data_type = TS_DATATYPE_INT64,
-                       .column_category = FIELD};
+        ColumnSchema{strdup("INT64"), TS_DATATYPE_INT64, FIELD};
     all_type_schema.column_schemas[3] =
-        (ColumnSchema){.column_name = strdup("FLOAT"),
-                       .data_type = TS_DATATYPE_FLOAT,
-                       .column_category = FIELD};
+        ColumnSchema{strdup("FLOAT"), TS_DATATYPE_FLOAT, FIELD};
     all_type_schema.column_schemas[4] =
-        (ColumnSchema){.column_name = strdup("DOUBLE"),
-                       .data_type = TS_DATATYPE_DOUBLE,
-                       .column_category = FIELD};
+        ColumnSchema{strdup("DOUBLE"), TS_DATATYPE_DOUBLE, FIELD};
     all_type_schema.column_schemas[5] =
-        (ColumnSchema){.column_name = strdup("BOOLEAN"),
-                       .data_type = TS_DATATYPE_BOOLEAN,
-                       .column_category = FIELD};
+        ColumnSchema{strdup("BOOLEAN"), TS_DATATYPE_BOOLEAN, FIELD};
 
     TsFileWriter writer =
         tsfile_writer_new(file, &all_type_schema, &error_code);
diff --git a/cpp/test/cwrapper/cwrapper_test.cc 
b/cpp/test/cwrapper/cwrapper_test.cc
index 90a93fb4..47e82402 100644
--- a/cpp/test/cwrapper/cwrapper_test.cc
+++ b/cpp/test/cwrapper/cwrapper_test.cc
@@ -17,7 +17,6 @@
  * under the License.
  */
 #include <gtest/gtest.h>
-#include <unistd.h>
 #include <utils/db_utils.h>
 extern "C" {
 #include "cwrapper/errno_define_c.h"
diff --git a/cpp/third_party/antlr4-cpp-runtime-4/CMakeLists.txt 
b/cpp/third_party/antlr4-cpp-runtime-4/CMakeLists.txt
index 9e293de7..312cb2c9 100644
--- a/cpp/third_party/antlr4-cpp-runtime-4/CMakeLists.txt
+++ b/cpp/third_party/antlr4-cpp-runtime-4/CMakeLists.txt
@@ -21,7 +21,7 @@ endif(NOT WITH_DEMO)
 
 option(WITH_LIBCXX "Building with clang++ and libc++(in Linux). To enable 
with: -DWITH_LIBCXX=On" Off)
 option(WITH_STATIC_CRT "(Visual C++) Enable to statically link CRT, which 
avoids requiring users to install the redistribution package.
- To disable with: -DWITH_STATIC_CRT=Off" On)
+ To disable with: -DWITH_STATIC_CRT=Off" OFF)
 
 project(LIBANTLR4)
 
diff --git a/cpp/third_party/antlr4-cpp-runtime-4/runtime/src/Vocabulary.cpp 
b/cpp/third_party/antlr4-cpp-runtime-4/runtime/src/Vocabulary.cpp
index 9bbf0b23..1b645f39 100755
--- a/cpp/third_party/antlr4-cpp-runtime-4/runtime/src/Vocabulary.cpp
+++ b/cpp/third_party/antlr4-cpp-runtime-4/runtime/src/Vocabulary.cpp
@@ -38,7 +38,7 @@ Vocabulary Vocabulary::fromTokenNames(const 
std::vector<std::string> &tokenNames
       continue;
     } else if (tokenName.front() == '\'') {
       symbolicNames[i].clear();
-    } else if (std::isupper(tokenName.front(), locale)) {
+    } else if (isupper(static_cast<unsigned char>(tokenName.front()))) {
       literalNames[i].clear();
     } else {
       // wasn't a literal or symbolic name


Reply via email to