Browse Source

Make GDNative DLLs work on UWP

George Marques 7 years ago
parent
commit
2a023a425d

+ 3 - 0
modules/gdnative/gdnative.cpp

@@ -130,6 +130,9 @@ bool GDNative::initialize() {
 	// we should pass library name to dlopen(). The library name is flattened
 	// during export.
 	String path = lib_path.get_file();
+#elif defined(UWP_ENABLED)
+	// On UWP we use a relative path from the app
+	String path = lib_path.replace("res://", "");
 #else
 	String path = ProjectSettings::get_singleton()->globalize_path(lib_path);
 #endif

+ 2 - 2
modules/gdnative/gdnative_library_editor_plugin.cpp

@@ -299,8 +299,8 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
 		NativePlatformConfig platform_uwp;
 		platform_uwp.name = "Windows Universal";
 		platform_uwp.entries.push_back("arm");
-		platform_uwp.entries.push_back("x86");
-		platform_uwp.entries.push_back("x64");
+		platform_uwp.entries.push_back("32");
+		platform_uwp.entries.push_back("64");
 		platform_uwp.library_extension = "*.dll";
 		platforms["UWP"] = platform_uwp;
 

+ 11 - 0
platform/uwp/export/export.cpp

@@ -1024,6 +1024,17 @@ public:
 	virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
 		r_features->push_back("s3tc");
 		r_features->push_back("etc");
+		switch ((int)p_preset->get("architecture/target")) {
+			case EditorExportUWP::ARM: {
+				r_features->push_back("arm");
+			} break;
+			case EditorExportUWP::X86: {
+				r_features->push_back("32");
+			} break;
+			case EditorExportUWP::X64: {
+				r_features->push_back("64");
+			} break;
+		}
 	}
 
 	virtual void get_export_options(List<ExportOption> *r_options) {

+ 45 - 0
platform/uwp/os_uwp.cpp

@@ -745,6 +745,51 @@ void OSUWP::hide_virtual_keyboard() {
 	pane->TryHide();
 }
 
+static String format_error_message(DWORD id) {
+
+	LPWSTR messageBuffer = NULL;
+	size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+			NULL, id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);
+
+	String msg = "Error " + itos(id) + ": " + String(messageBuffer, size);
+
+	LocalFree(messageBuffer);
+
+	return msg;
+}
+
+Error OSUWP::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
+
+	String full_path = "game/" + p_path;
+	p_library_handle = (void *)LoadPackagedLibrary(full_path.c_str(), 0);
+
+	if (!p_library_handle) {
+		ERR_EXPLAIN("Can't open dynamic library: " + full_path + ". Error: " + format_error_message(GetLastError()));
+		ERR_FAIL_V(ERR_CANT_OPEN);
+	}
+	return OK;
+}
+
+Error OSUWP::close_dynamic_library(void *p_library_handle) {
+	if (!FreeLibrary((HMODULE)p_library_handle)) {
+		return FAILED;
+	}
+	return OK;
+}
+
+Error OSUWP::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) {
+	p_symbol_handle = (void *)GetProcAddress((HMODULE)p_library_handle, p_name.utf8().get_data());
+	if (!p_symbol_handle) {
+		if (!p_optional) {
+			ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + String::num(GetLastError()));
+			ERR_FAIL_V(ERR_CANT_RESOLVE);
+		} else {
+			return ERR_CANT_RESOLVE;
+		}
+	}
+	return OK;
+}
+
 void OSUWP::run() {
 
 	if (!main_loop)

+ 4 - 0
platform/uwp/os_uwp.h

@@ -242,6 +242,10 @@ public:
 	virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2());
 	virtual void hide_virtual_keyboard();
 
+	virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
+	virtual Error close_dynamic_library(void *p_library_handle);
+	virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
+
 	virtual Error shell_open(String p_uri);
 
 	void run();