mirror of
https://github.com/godotengine/godot.git
synced 2024-11-28 23:22:38 +00:00
Mono/C#: Fix Android AAB export failing to load native libs
By default, when installing from Android App Bundles the native libraries are not extracted. They are loaded directly from the APK. See: https://stackoverflow.com/a/56551499 Passing only the file name to dlopen, without the location, makes it search the native library in all locations, including inside the apk.
This commit is contained in:
parent
afadd3d12e
commit
c7f716e2ea
@ -164,11 +164,12 @@ const char *godot_so_name = "libgodot_android.so";
|
||||
void *mono_dl_handle = NULL;
|
||||
void *godot_dl_handle = NULL;
|
||||
|
||||
void *try_dlopen(const String &p_so_path, int p_flags) {
|
||||
void *_try_dlopen_file_path(const String &p_so_path, int p_flags) {
|
||||
if (!FileAccess::exists(p_so_path)) {
|
||||
if (OS::get_singleton()->is_stdout_verbose())
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
OS::get_singleton()->print("Cannot find shared library: '%s'\n", p_so_path.utf8().get_data());
|
||||
return NULL;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int lflags = gd_mono_convert_dl_flags(p_flags);
|
||||
@ -176,13 +177,48 @@ void *try_dlopen(const String &p_so_path, int p_flags) {
|
||||
void *handle = dlopen(p_so_path.utf8().get_data(), lflags);
|
||||
|
||||
if (!handle) {
|
||||
if (OS::get_singleton()->is_stdout_verbose())
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
OS::get_singleton()->print("Failed to open shared library: '%s'. Error: '%s'\n", p_so_path.utf8().get_data(), dlerror());
|
||||
return NULL;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (OS::get_singleton()->is_stdout_verbose())
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
OS::get_singleton()->print("Successfully loaded shared library: '%s'\n", p_so_path.utf8().get_data());
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void *try_dlopen(const String &p_so_path, int p_flags) {
|
||||
void *handle = _try_dlopen_file_path(p_so_path, p_flags);
|
||||
|
||||
if (handle) {
|
||||
return handle;
|
||||
}
|
||||
|
||||
// Try only with the file name, without specifying the location.
|
||||
// This is needed when installing from Android App Bundles, as the native
|
||||
// libraries are not extracted. They are loaded directly from the APK.
|
||||
// See: https://stackoverflow.com/a/56551499
|
||||
// If we pass only the file name to dlopen without the location, it should
|
||||
// search the native libraries in all locations, including inside the apk.
|
||||
|
||||
String so_name = p_so_path.get_file();
|
||||
|
||||
int lflags = gd_mono_convert_dl_flags(p_flags);
|
||||
|
||||
handle = dlopen(so_name.utf8().get_data(), lflags);
|
||||
if (!handle) {
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
OS::get_singleton()->print("Failed to open shared library: '%s'. Error: '%s'\n", so_name.utf8().get_data(), dlerror());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
OS::get_singleton()->print("Successfully loaded shared library: '%s'\n", so_name.utf8().get_data());
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
@ -196,6 +232,7 @@ void *gd_mono_android_dlopen(const char *p_name, int p_flags, char **r_err, void
|
||||
String so_path = path::join(app_native_lib_dir, mono_so_name);
|
||||
|
||||
mono_dl_handle = try_dlopen(so_path, p_flags);
|
||||
ERR_FAIL_COND_V_MSG(!mono_dl_handle, nullptr, "Failed to load Mono native library from path");
|
||||
}
|
||||
|
||||
return mono_dl_handle;
|
||||
@ -371,7 +408,7 @@ void initialize() {
|
||||
String so_path = path::join(app_native_lib_dir, godot_so_name);
|
||||
|
||||
godot_dl_handle = try_dlopen(so_path, gd_mono_convert_dl_flags(MONO_DL_LAZY));
|
||||
ERR_FAIL_COND(!godot_dl_handle);
|
||||
ERR_FAIL_COND_MSG(!godot_dl_handle, "Failed to load Godot native library");
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
|
Loading…
Reference in New Issue
Block a user