wip: Add some Windows impl

This commit is contained in:
DaLaw2 2026-01-04 18:44:12 +08:00
parent c93b7c4782
commit 8ecd5787cd
12 changed files with 270 additions and 28 deletions

View File

@ -5,11 +5,12 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (WIN32)
set(PLATFORM_SOURCES src/win32/win32_handle.cpp)
set(PLATFORM_HEADERS include/shmcpp/detail/win32_handle.hpp)
set(PLATFORM_SOURCES src/win32/handle.cpp)
set(PLATFORM_HEADERS include/shmcpp/detail/win32/handle.hpp
include/shmcpp/detail/win32/utils.hpp)
else ()
set(PLATFORM_SOURCES src/posix/posix_handle.cpp)
set(PLATFORM_HEADERS include/shmcpp/detail/posix_handle.hpp)
set(PLATFORM_SOURCES src/posix/handle.cpp)
set(PLATFORM_HEADERS include/shmcpp/detail/posix/handle.hpp)
endif ()
add_library(shmcpp STATIC

View File

@ -5,4 +5,27 @@
#ifndef SHMCPP_HANDLE_CONCEPT_HPP
#define SHMCPP_HANDLE_CONCEPT_HPP
#endif //SHMCPP_HANDLE_CONCEPT_HPP
#include <concepts>
#include <cstddef>
#include <string>
#include <shmcpp/mapped_view.hpp>
namespace shmcpp::detail {
template<class T>
concept Handle =
std::movable<T> &&
!std::copyable<T> &&
requires(T handle,
const std::string &name,
std::size_t size,
std::size_t offset,
std::size_t length)
{
{ T::create(name, size) } -> std::same_as<T>;
{ T::open(name, size) } -> std::same_as<T>;
{ handle.map(offset, length) } -> std::same_as<MappedView>;
{ handle.size() } -> std::convertible_to<std::size_t>;
};
}
#endif //SHMCPP_HANDLE_CONCEPT_HPP

View File

@ -0,0 +1,37 @@
//
// Created by DaLaw2 on 2026/1/3.
//
#ifndef SHMCPP_POSIX_HANDLE_HPP
#define SHMCPP_POSIX_HANDLE_HPP
#include <shmcpp/detail/handle_concept.hpp>
namespace shmcpp::detail {
class PosixHandle {
int fd_;
std::size_t size_;
public:
PosixHandle() = delete;
~PosixHandle() noexcept;
PosixHandle(const PosixHandle &) = delete;
PosixHandle &operator=(const PosixHandle &) = delete;
PosixHandle(PosixHandle &&) noexcept;
PosixHandle &operator=(PosixHandle &&) noexcept;
static PosixHandle create(const std::string &name, std::size_t size);
static PosixHandle open(const std::string &name, std::size_t size);
MappedView map(std::size_t offset, std::size_t length);
[[nodiscard]] std::size_t size() const;
};
}
#endif //SHMCPP_POSIX_HANDLE_HPP

View File

@ -1,8 +0,0 @@
//
// Created by DaLaw2 on 2026/1/3.
//
#ifndef SHMCPP_POSIX_HANDLE_HPP
#define SHMCPP_POSIX_HANDLE_HPP
#endif //SHMCPP_POSIX_HANDLE_HPP

View File

@ -0,0 +1,43 @@
//
// Created by DaLaw2 on 2026/1/3.
//
#ifndef SHMCPP_WIN32_HANDLE_HPP
#define SHMCPP_WIN32_HANDLE_HPP
#include <string>
#include <cstddef>
#include <windows.h>
#include <shmcpp/detail/handle_concept.hpp>
namespace shmcpp::detail {
class Win32Handle {
HANDLE handle_ = INVALID_HANDLE_VALUE;
std::size_t size_ = 0;
Win32Handle(HANDLE handle, std::size_t size) noexcept;
public:
Win32Handle() = delete;
~Win32Handle() noexcept;
Win32Handle(const Win32Handle &) = delete;
Win32Handle &operator=(const Win32Handle &) = delete;
Win32Handle(Win32Handle &&) noexcept;
Win32Handle &operator=(Win32Handle &&) noexcept;
static Win32Handle create(const std::string &name, std::size_t size);
static Win32Handle open(const std::string &name, std::size_t size);
MappedView map(std::size_t offset, std::size_t length);
[[nodiscard]] std::size_t size() const;
};
}
#endif //SHMCPP_WIN32_HANDLE_HPP

View File

@ -0,0 +1,43 @@
//
// Created by DaLaw2 on 2026/1/4.
//
#ifndef SHMCPP_UTILS_HPP
#define SHMCPP_UTILS_HPP
#include <windows.h>
#include <string>
namespace shmcpp::detail {
inline std::string getWindowsErrorMessage(const DWORD errorCode) noexcept {
LPSTR messageBuffer = nullptr;
std::size_t size = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPSTR>(&messageBuffer),
0,
nullptr
);
if (size == 0) {
return "Unknown error";
}
std::string message(messageBuffer, size);
LocalFree(messageBuffer);
while (!message.empty() && (message.back() == '\n' || message.back() == '\r')) {
message.pop_back();
}
return message;
}
}
#endif //SHMCPP_UTILS_HPP

View File

@ -1,8 +0,0 @@
//
// Created by DaLaw2 on 2026/1/3.
//
#ifndef SHMCPP_WIN32_HANDLE_HPP
#define SHMCPP_WIN32_HANDLE_HPP
#endif //SHMCPP_WIN32_HANDLE_HPP

View File

@ -5,4 +5,26 @@
#ifndef SHMCPP_MAPPED_VIEW_HPP
#define SHMCPP_MAPPED_VIEW_HPP
#endif //SHMCPP_MAPPED_VIEW_HPP
#include <cstddef>
namespace shmcpp {
class MappedView {
void *data_ = nullptr;
std::size_t size_ = 0;
public:
MappedView() = delete;
MappedView(void *data, std::size_t size) noexcept;
~MappedView() noexcept;
MappedView(const MappedView &) = delete;
MappedView(MappedView &&) noexcept;
MappedView &operator=(const MappedView &) noexcept;
};
}
#endif //SHMCPP_MAPPED_VIEW_HPP

9
src/posix/handle.cpp Normal file
View File

@ -0,0 +1,9 @@
//
// Created by DaLaw2 on 2026/1/3.
//
#include "shmcpp/detail/posix/handle.hpp"
namespace shmcpp::detail {
static_assert(Handle<PosixHandle>);
}

View File

@ -1,3 +0,0 @@
//
// Created by DaLaw2 on 2026/1/3.
//

86
src/win32/handle.cpp Normal file
View File

@ -0,0 +1,86 @@
//
// Created by DaLaw2 on 2026/1/3.
//
#include <format>
#include <stdexcept>
#include "shmcpp/detail/win32/utils.hpp"
#include "shmcpp/detail/win32/handle.hpp"
namespace shmcpp::detail {
Win32Handle::Win32Handle(const HANDLE handle, const std::size_t size) noexcept
: handle_(handle), size_(size) {
}
Win32Handle::~Win32Handle() {
if (handle_ != INVALID_HANDLE_VALUE) {
CloseHandle(handle_);
}
}
Win32Handle::Win32Handle(Win32Handle &&other) noexcept {
this->handle_ = other.handle_;
this->size_ = other.size_;
other.handle_ = INVALID_HANDLE_VALUE;
other.size_ = 0;
}
Win32Handle &Win32Handle::operator=(Win32Handle &&other) noexcept {
if (this != &other) {
if (handle_ != INVALID_HANDLE_VALUE) {
CloseHandle(handle_);
}
this->handle_ = other.handle_;
this->size_ = other.size_;
other.handle_ = INVALID_HANDLE_VALUE;
other.size_ = 0;
}
return *this;
}
Win32Handle Win32Handle::create(const std::string &name, const std::size_t size) {
const DWORD high = size >> 32;
const DWORD low = size & 0xFFFFFFFF;
const HANDLE handle = CreateFileMappingA(
INVALID_HANDLE_VALUE,
nullptr,
PAGE_READWRITE,
high,
low,
name.c_str()
);
if (handle == nullptr) {
DWORD err = GetLastError();
throw std::runtime_error(
std::format("{}: {}", err, getWindowsErrorMessage(err))
);
}
return Win32Handle{handle, size};
}
Win32Handle Win32Handle::open(const std::string &name, const std::size_t size) {
const HANDLE handle = OpenFileMappingA(
FILE_ALL_ACCESS,
FALSE,
name.c_str()
);
if (handle == nullptr) {
DWORD err = GetLastError();
throw std::runtime_error(
std::format("{}: {}", err, getWindowsErrorMessage(err))
);
}
return Win32Handle{handle, size};
}
MappedView Win32Handle::map(std::size_t offset, std::size_t length) {
return {};
}
size_t Win32Handle::size() const {
return this->size_;
}
static_assert(Handle<Win32Handle>);
}

View File

@ -1,3 +0,0 @@
//
// Created by DaLaw2 on 2026/1/3.
//