xamarin-macios/runtime/mono-runtime.m.t4

122 строки
3.5 KiB
C

// 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 <rolf@xamarin.com>
// Aaron Bockover <abock@xamarin.com>
//
// Copyright 2013-2014 Xamarin Inc.
//
<#@ include file="exports.t4" #>
#ifdef DYNAMIC_MONO_RUNTIME
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <dlfcn.h>
#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 */