[csharp,iOS] Fix callbacks on AOT #386

Closed
rmarinho wants to merge 6 commits from fix-logger-xamarinios into master
3 changed files with 61 additions and 23 deletions
Showing only changes of commit 7cbfecd6a9 - Show all commits

View File

@@ -8,17 +8,14 @@
*/
using System;
using System.Runtime.InteropServices;
namespace Facebook.Yoga
{
internal static class YogaLogger
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void Func(YogaLogLevel level, string message);
private static bool _initialized;
private static Func _managedLogger = null;
public static Func Logger = null;
@@ -26,42 +23,27 @@ namespace Facebook.Yoga
{
if (!_initialized)
{
_managedLogger = (level, message) => {
if (Logger != null)
{
Logger(level, message);
}
if (level == YogaLogLevel.Error)
{
throw new InvalidOperationException(message);
}
};
#if __IOS__
Native.YGInteropSetLogger(ManagedLogger);
#else
Native.YGInteropSetLogger(_managedLogger);
#endif
Native.YGInteropSetLogger(LoggerInternal);
_initialized = true;
}
}
#if __IOS__
delegate void ManagedLoggerCallback(YogaLogLevel level, string message);
[ObjCRuntime.MonoPInvokeCallback(typeof(ManagedLoggerCallback))]
public static void ManagedLogger(YogaLogLevel level, string message)
{
if (Logger != null)
{
Logger(level, message);
}
if (level == YogaLogLevel.Error)
{
throw new InvalidOperationException(message);
}
}
[ObjCRuntime.MonoPInvokeCallback(typeof(Func))]
#endif
public static void LoggerInternal(YogaLogLevel level, string message)
{
if (Logger != null)
{
Logger(level, message);
}
if (level == YogaLogLevel.Error)
rolfbjarne commented 2017-02-13 00:11:20 -08:00 (Migrated from github.com)
Review

You need to store the delegate in a static field, otherwise the GC will collect it and the app will crash when the callback is called:

static Func _logger_internal = LoggerInternal;

Native.YGInteropSetLogger (_logger_internal);
You need to store the delegate in a static field, otherwise the GC will collect it and the app will crash when the callback is called: static Func _logger_internal = LoggerInternal; Native.YGInteropSetLogger (_logger_internal);
rmarinho commented 2017-02-13 02:33:47 -08:00 (Migrated from github.com)
Review

@splhack can you take a note on this in your PR ?

@splhack can you take a note on this in your PR ?
splhack commented 2017-02-13 08:40:37 -08:00 (Migrated from github.com)
Review

sure

sure
{
throw new InvalidOperationException(message);
}
}
}
}