// vim: set filetype=c : // // mono-runtime.m: Header file to allow dynamic loading of Mono to // be transparent from code including the mono-runtime.h header. // // Authors: // Rolf Bjarne Kvinge // Aaron Bockover // // Copyright 2013-2014 Xamarin Inc. // <#@ include file="exports.t4" #> #ifdef DYNAMIC_MONO_RUNTIME #include #include #include #include #include #include "xamarin/main.h" #include "xamarin/mono-runtime.h" #include "xamarin/runtime.h" #include "product.h" #include "runtime-internal.h" <# foreach (var export in exports) { #> <#= export.DotNetIf #>typedef <#= export.ReturnType #> (* <#= export.EntryPoint #>_def) (<#= export.ArgumentSignature #>); <#= export.DotNetEndIf #><# } #> <# foreach (var export in exports) { #> <#= export.DotNetIf #><#= export.EntryPoint #>_def <#= export.EntryPoint #>_func = NULL; <#= export.DotNetEndIf #><# } #> char * xamarin_get_mono_runtime_build_info () { if (!mono_get_runtime_build_info_func) return NULL; return mono_get_runtime_build_info_func (); } static char xamarin_dynamic_runtime_initialized = 0; const char * xamarin_initialize_dynamic_runtime (const char *mono_runtime_prefix) { if (xamarin_dynamic_runtime_initialized) return NULL; void *libmono = NULL; const char *errmsg = NULL; // Check if we already have mono available. // RTLD_DEFAULT is the catch-all, but it's slow (according to the dlsym man page), // so try MAIN_ONLY and SELF first to see if we can optimize a bit. if (dlsym (RTLD_MAIN_ONLY, "mono_get_runtime_build_info")) { libmono = RTLD_MAIN_ONLY; } else if (dlsym (RTLD_SELF, "mono_get_runtime_build_info")) { libmono = RTLD_SELF; } else if (dlsym (RTLD_DEFAULT, "mono_get_runtime_build_info")) { libmono = RTLD_DEFAULT; } else if (mono_runtime_prefix != NULL) { NSString *dylib = [[NSString stringWithUTF8String: mono_runtime_prefix] stringByAppendingPathComponent: @"/lib/libmonosgen-2.0.dylib"]; libmono = dlopen ([dylib UTF8String], RTLD_LAZY); } if (libmono == NULL) { const char *dlopen_err = dlerror (); if (dlopen_err != NULL) PRINT (PRODUCT ": dlopen error: %s", dlopen_err); return "This application requires the Mono framework."; } <# foreach (var export in exports) { #> <#= export.DotNetIf #><#= export.RuntimeIf #> <#= export.EntryPoint #>_func = (<#= export.EntryPoint #>_def) dlsym (libmono, "<#= export.EntryPoint #>"); <# if (!export.Optional) { #> if (<#= export.EntryPoint #>_func == NULL) { fprintf (stderr, "Could not load <#= export.EntryPoint #>\n"); errmsg = "Failed to load the Mono framework."; } <# } #> <#= export.DotNetEndIf #><#= export.RuntimeEndIf #> <# } #> xamarin_dynamic_runtime_initialized = 1; return errmsg; } <# foreach (var export in exports) { #> <#= export.DotNetIf #>MONO_API <#= export.ReturnType #> <#= export.EntryPoint #> (<#= export.ArgumentSignature #>) { <# if (export.Optional) { #> if (<#= export.EntryPoint #>_func == NULL) <# if (!string.IsNullOrEmpty (export.AlternativeExpression)) { #> <#= export.AlternativeExpression #> <# } else {#> xamarin_assertion_message ("Could not load <#= export.EntryPoint #>\n"); <# } #> <# } #> return <#= export.EntryPoint #>_func (<#= export.ArgumentNames #>); } <#= export.DotNetEndIf #><# } #> <# foreach (var export in exports) { if (!export.Optional) continue; #> bool <#= export.EntryPoint #>_exists () { return <#= export.EntryPoint #>_func != NULL; } <# } #> #else int xamarin_fix_ranlib_warning_about_no_symbols; #endif /* DYNAMIC_MONO_RUNTIME */