122 строки
3.5 KiB
C
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 */
|