Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows: DLL support #418

Open
Ghabry opened this issue Mar 31, 2021 · 0 comments
Open

Windows: DLL support #418

Ghabry opened this issue Mar 31, 2021 · 0 comments

Comments

@Ghabry
Copy link
Member

Ghabry commented Mar 31, 2021

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

1 participant