Skip to content

Commit 30ced74

Browse files
committed
Stop using __Internal in our p/invoke calls
Context: dotnet#4914 Context: dotnet@d583b7c The .NET5 version of the Mono runtime "hijacked" `__Internal` for its own purposes and the change causes us trouble when trying to resolve p/invokes from our managed code to our runtime. Instead we now use `xa-internal-api` (added in d583b7c) to specify the p/invoke library name.
1 parent 51f56aa commit 30ced74

File tree

8 files changed

+100
-34
lines changed

8 files changed

+100
-34
lines changed

src/Mono.Android/Android.Runtime/AndroidEnvironment.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ static string GetDefaultTimeZone ()
280280
}
281281
}
282282

283-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
283+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
284284
static extern IntPtr _monodroid_timezone_get_default_id ();
285285

286286
// This is invoked by
@@ -301,7 +301,7 @@ static string GetDefaultTimeZone ()
301301
// These are invoked by
302302
// System.dll!System.AndroidPlatform.getifaddrs
303303
// DO NOT REMOVE
304-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
304+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
305305
static extern int _monodroid_getifaddrs (out IntPtr ifap);
306306

307307
static int GetInterfaceAddresses (out IntPtr ifap)
@@ -312,15 +312,15 @@ static int GetInterfaceAddresses (out IntPtr ifap)
312312
// These are invoked by
313313
// System.dll!System.AndroidPlatform.freeifaddrs
314314
// DO NOT REMOVE
315-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
315+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
316316
static extern void _monodroid_freeifaddrs (IntPtr ifap);
317317

318318
static void FreeInterfaceAddresses (IntPtr ifap)
319319
{
320320
_monodroid_freeifaddrs (ifap);
321321
}
322322

323-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
323+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
324324
static extern void _monodroid_detect_cpu_and_architecture (ref ushort built_for_cpu, ref ushort running_on_cpu, ref byte is64bit);
325325

326326
static void DetectCPUAndArchitecture (out ushort builtForCPU, out ushort runningOnCPU, out bool is64bit)

src/Mono.Android/Android.Runtime/AndroidRuntime.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace Android.Runtime {
1616

1717
class AndroidRuntime : JniRuntime {
1818

19+
public const string InternalDllName = "xa-internal-api";
20+
1921
internal AndroidRuntime (IntPtr jnienv,
2022
IntPtr vm,
2123
bool allocNewObjectSupported,
@@ -100,7 +102,7 @@ public AndroidRuntimeOptions (IntPtr jnienv,
100102

101103
class AndroidObjectReferenceManager : JniRuntime.JniObjectReferenceManager {
102104

103-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
105+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
104106
static extern int _monodroid_gref_get ();
105107

106108
public override int GlobalReferenceCount {

src/Mono.Android/Android.Runtime/JNIEnv.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,16 @@ public static partial class JNIEnv {
6666

6767
internal static AndroidValueManager? AndroidValueManager;
6868

69-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
69+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
7070
extern static void monodroid_log (LogLevel level, LogCategories category, string message);
7171

72-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
72+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
7373
internal extern static IntPtr monodroid_timing_start (string? message);
7474

75-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
75+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
7676
internal extern static void monodroid_timing_stop (IntPtr sequence, string? message);
7777

78-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
78+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
7979
internal extern static void monodroid_free (IntPtr ptr);
8080

8181
public static IntPtr Handle {
@@ -296,7 +296,7 @@ internal static void PropagateUncaughtException (IntPtr env, IntPtr javaThreadPt
296296
}
297297
}
298298

299-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
299+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
300300
extern static void _monodroid_gc_wait_for_bridge_processing ();
301301

302302
#pragma warning disable CS0649 // Field is never assigned to. This field is assigned from monodroid-glue.cc.
@@ -310,7 +310,7 @@ public static void WaitForBridgeProcessing ()
310310
_monodroid_gc_wait_for_bridge_processing ();
311311
}
312312

313-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
313+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
314314
extern static IntPtr _monodroid_get_identity_hash_code (IntPtr env, IntPtr value);
315315

316316
internal static Func<IntPtr, IntPtr>? IdentityHash;
@@ -597,25 +597,25 @@ internal static void DeleteRef (IntPtr handle, JniHandleOwnership transfer)
597597
}
598598
}
599599

600-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
600+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
601601
internal static extern int _monodroid_gref_log (string message);
602602

603-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
603+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
604604
internal static extern int _monodroid_gref_log_new (IntPtr curHandle, byte curType, IntPtr newHandle, byte newType, string? threadName, int threadId, [In] StringBuilder? from, int from_writable);
605605

606-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
606+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
607607
internal static extern void _monodroid_gref_log_delete (IntPtr handle, byte type, string? threadName, int threadId, [In] StringBuilder? from, int from_writable);
608608

609-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
609+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
610610
internal static extern void _monodroid_weak_gref_new (IntPtr curHandle, byte curType, IntPtr newHandle, byte newType, string? threadName, int threadId, [In] StringBuilder? from, int from_writable);
611611

612-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
612+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
613613
internal static extern void _monodroid_weak_gref_delete (IntPtr handle, byte type, string? threadName, int threadId, [In] StringBuilder? from, int from_writable);
614614

615-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
615+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
616616
internal static extern int _monodroid_lref_log_new (int lrefc, IntPtr handle, byte type, string? threadName, int threadId, [In] StringBuilder from, int from_writable);
617617

618-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
618+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
619619
internal static extern void _monodroid_lref_log_delete (int lrefc, IntPtr handle, byte type, string? threadName, int threadId, [In] StringBuilder from, int from_writable);
620620

621621
public static IntPtr NewGlobalRef (IntPtr jobject)

src/Mono.Android/Android.Runtime/Logger.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public static void Log (LogLevel level, string appname, string? log) {
6060
}
6161
}
6262

63-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
63+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
6464
extern static uint monodroid_get_log_categories ();
6565

6666
static Logger ()

src/Mono.Android/Java.Interop/Runtime.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ public static List<WeakReference> GetSurfacedObjects ()
2020
return r;
2121
}
2222

23-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
23+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
2424
static extern int _monodroid_max_gref_get ();
2525

2626
public static int MaxGlobalReferenceCount {
2727
get {return _monodroid_max_gref_get ();}
2828
}
2929

30-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
30+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
3131
static extern int _monodroid_gref_get ();
3232

3333
public static int GlobalReferenceCount {

src/Mono.Android/Java.Interop/TypeManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public static Dictionary<Type, string> ManagedToJni {
3838
}
3939

4040
public static partial class TypeManager {
41-
[DllImport ("__Internal", CallingConvention = CallingConvention.Cdecl)]
41+
[DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
4242
extern static IntPtr monodroid_TypeManager_get_java_class_name (IntPtr klass);
4343

4444
internal static string GetClassName (IntPtr class_ptr)

src/monodroid/jni/monodroid-glue.cc

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,27 +1151,91 @@ MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err, [[m
11511151
{
11521152
unsigned int dl_flags = monodroidRuntime.convert_dl_flags (flags);
11531153
bool libmonodroid_fallback = false;
1154-
1154+
bool name_is_full_path = false;
1155+
bool name_needs_free = false;
11551156
/* name is nullptr when we're P/Invoking __Internal, so remap to libxa-internal-api */
1156-
if (name == nullptr) {
1157+
if (name == nullptr || strstr (name, "xa-internal-api") != nullptr) {
1158+
#if defined (WINDOWS)
1159+
char *tmp_name = nullptr;
1160+
1161+
auto probe_dll_at = [&](const char *the_path) -> bool {
1162+
const char *last_sep = strrchr (the_path, MONODROID_PATH_SEPARATOR_CHAR);
1163+
if (last_sep != nullptr) {
1164+
tmp_name = utils.strdup_new (the_path, last_sep - the_path);
1165+
tmp_name = utils.string_concat (tmp_name, MONODROID_PATH_SEPARATOR, API_DSO_NAME);
1166+
if (!utils.file_exists (tmp_name)) {
1167+
delete[] tmp_name;
1168+
tmp_name = nullptr;
1169+
return false;
1170+
}
1171+
1172+
return true;
1173+
}
1174+
1175+
return false;
1176+
};
1177+
1178+
// First try to see if it exist at the path pointed to by `name`. With p/invokes, currently (Sep 2020), we can't
1179+
// really trust the path since it consists of *some* directory path + p/invoke library name and it does not
1180+
// point to the location where the native library is. However, we still need to check the location first, should
1181+
// it point to the right place in the future.
1182+
bool found = probe_dll_at (name);
1183+
if (!found) {
1184+
// Next lets try the location of the XA runtime DLL, libxa-internal-api.dll should be next to it.
1185+
HMODULE hm;
1186+
const void *func = reinterpret_cast<const void*>(&Java_mono_android_Runtime_initInternal);
1187+
if (GetModuleHandleEx (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, static_cast<LPCSTR>(func), &hm) == 0) {
1188+
log_fatal (LOG_DEFAULT, "Failed to get module handle for the Xamarin.Android runtime");
1189+
exit (1);
1190+
}
1191+
1192+
char path[MAX_PATH];
1193+
if (GetModuleFileName (hm, path, sizeof(path)) == 0) {
1194+
log_fatal (LOG_DEFAULT, "Failed to obtain path of the Xamarin.Android runtime");
1195+
exit (1);
1196+
}
1197+
1198+
found = probe_dll_at (path);
1199+
if (!found) {
1200+
log_warn (LOG_DEFAULT, "Failed to locate %s, using file name without the path", API_DSO_NAME);
1201+
name = API_DSO_NAME;
1202+
} else {
1203+
name = tmp_name;
1204+
name_is_full_path = true;
1205+
name_needs_free = true;
1206+
}
1207+
}
1208+
#else
11571209
name = API_DSO_NAME;
1210+
#endif
11581211
libmonodroid_fallback = true;
11591212
}
11601213

1161-
void *h = androidSystem.load_dso_from_any_directories (name, dl_flags);
1214+
void *h = nullptr;
1215+
if (!name_is_full_path)
1216+
h = androidSystem.load_dso_from_any_directories (name, dl_flags);
11621217

11631218
if (h != nullptr) {
1164-
return monodroid_dlopen_log_and_return (h, err, name, false, libmonodroid_fallback);
1219+
return monodroid_dlopen_log_and_return (h, err, name, name_needs_free, libmonodroid_fallback);
11651220
}
11661221

11671222
if (libmonodroid_fallback) {
1168-
char *full_name = utils.path_combine (AndroidSystem::SYSTEM_LIB_PATH, API_DSO_NAME);
1223+
const char *full_name;
1224+
if (name_is_full_path) {
1225+
full_name = name;
1226+
} else {
1227+
if (name_needs_free) {
1228+
delete[] name;
1229+
}
1230+
full_name = utils.path_combine (AndroidSystem::SYSTEM_LIB_PATH, API_DSO_NAME);
1231+
name_needs_free = true;
1232+
}
11691233
h = androidSystem.load_dso (full_name, dl_flags, false);
1170-
return monodroid_dlopen_log_and_return (h, err, full_name, true, true);
1234+
return monodroid_dlopen_log_and_return (h, err, full_name, name_needs_free, true);
11711235
}
11721236

11731237
if (!utils.ends_with (name, ".dll.so") && !utils.ends_with (name, ".exe.so")) {
1174-
return monodroid_dlopen_log_and_return (h, err, name, false);
1238+
return monodroid_dlopen_log_and_return (h, err, name, name_needs_free);
11751239
}
11761240

11771241
char *basename_part = const_cast<char*> (strrchr (name, '/'));
@@ -1186,6 +1250,10 @@ MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err, [[m
11861250
if (h != nullptr && XA_UNLIKELY (utils.should_log (LOG_ASSEMBLY)))
11871251
log_info_nocheck (LOG_ASSEMBLY, "Loaded AOT image '%s'", static_cast<const char*>(basename));
11881252

1253+
if (name_needs_free) {
1254+
delete[] name;
1255+
}
1256+
11891257
return h;
11901258
}
11911259

tests/MSBuildDeviceIntegration/Tests/XASdkDeployTests.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,7 @@ public void DotNetDebug ()
5555
AssertHasDevices ();
5656

5757
XASdkProject proj;
58-
proj = new XASdkProject {
59-
//TODO: targetSdkVersion="30" causes a crash on startup in .NET 5
60-
MinSdkVersion = null,
61-
TargetSdkVersion = null,
62-
};
58+
proj = new XASdkProject ();
6359
proj.SetRuntimeIdentifier (DeviceAbi);
6460

6561
var relativeProjDir = Path.Combine ("temp", TestName);

0 commit comments

Comments
 (0)