Skip to content

Windows: DLL support #418

@Ghabry

Description

@Ghabry

In terms of being compatible with LGPL using DLLs makes sense for commercial games. Mixing shared and static libs is a bit chaotic on Windows so it would make sense to also distribute liblcf as a DLL in this case.

Currently liblcf can be only used as a static library on Windows because the way how DLLs work is special:

All functions and static fields must be dllexported.

CMake has "magic" to do this but it will only work for functions:

set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS ON)

After this there is exactly one linker error left which is about:

static const size_type _empty_buf[2];

This is a static data field (and the only one we have in liblcf it seems :).

For data fields the process is even more ugly: You must determine whether you are currently compiling the DLL or using the DLL. In case of compiling you must dllexport it in case of using you must import the field.

This is quite disgusting imo. A solution would be to move the field into the cpp file. This has the disadvantage that inlining of the empty buf field will not work anymore (at least not without link time codegen):

@fmatthew5876 As you wrote this code: Do you see a problem with the shown solution:

diff --git a/src/dbarray.cpp b/src/dbarray.cpp
index 9d2dc9d..d3052b4 100644
--- a/src/dbarray.cpp
+++ b/src/dbarray.cpp
@@ -12,7 +12,7 @@
 
 namespace lcf {
 
-const DBArrayAlloc::size_type DBArrayAlloc::_empty_buf[2] = { 0, 0 };
+static const DBArrayAlloc::size_type _empty_buf[2] = { 0, 0 };
 constexpr DBString::size_type DBString::npos;
 
 static ptrdiff_t HeaderSize(size_t align) {
@@ -63,6 +63,10 @@ void DBArrayAlloc::free(void* p, size_type align) noexcept {
 	}
 }
 
+void* DBArrayAlloc::empty_buf() {
+	return const_cast<size_type*>(&_empty_buf[1]);
+}
+
 char* DBString::construct_z(const char* s, size_t len) {
 	auto* p = alloc(len);
 	if (len) {
diff --git a/src/lcf/dbarrayalloc.h b/src/lcf/dbarrayalloc.h
index 328f61d..06ab817 100644
--- a/src/lcf/dbarrayalloc.h
+++ b/src/lcf/dbarrayalloc.h
@@ -25,10 +25,7 @@ struct DBArrayAlloc {
 
 	static void* alloc(size_type size, size_type field_size, size_type align);
 	static void free(void* p, size_type align) noexcept;
-
-	static void* empty_buf() {
-		return const_cast<size_type*>(&_empty_buf[1]);
-	}
+	static void* empty_buf();
 
 	static constexpr size_type* get_size_ptr(void* p) {
 		return static_cast<size_type*>(p) - 1;
@@ -37,9 +34,6 @@ struct DBArrayAlloc {
 	static constexpr const size_type* get_size_ptr(const void* p) {
 		return static_cast<const size_type*>(p) - 1;
 	}
-
-	private:
-	static const size_type _empty_buf[2];
 };
 
 } // namespace lcf

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions