3bb1ac6bff637b4e8e0c60396dc382786c502dbc
[mono.git] / mono / utils / mono-embed.c
1 /*
2  * mono-embed.c: Example code APIs to register a libraries using
3  * mono_dl_fallback_register.  Real implementations should instead
4  * use a binary search for implementing the dl_mapping_open and
5  * dl_mapping_symbol methods here.
6  *
7  * Author:
8  *    Mono Team (http://www.mono-project.com)
9  *
10  * Copyright 2001-2004 Ximian, Inc.
11  * Copyright 2004-2010 Novell, Inc.
12  *
13  */
14 #include "config.h"
15 #include "mono/utils/mono-dl.h"
16 #include "mono/utils/mono-embed.h"
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <ctype.h>
21 #include <string.h>
22 #include <glib.h>
23
24 static GHashTable *mono_dls;
25
26 static void *
27 dl_mapping_open (const char *file, int flags, char **err, void *user_data)
28 {
29         MonoDlMapping *mappings;
30         
31         if (mono_dls == NULL){
32                 *err = g_strdup ("Library not registered");
33                 return NULL;
34         }
35                 
36         mappings = (MonoDlMapping *) g_hash_table_lookup (mono_dls, file);
37         *err = g_strdup (mappings == NULL ? "File not registered" : "");
38         return mappings;
39 }
40
41 static void *
42 dl_mapping_symbol (void *handle, const char *symbol, char **err, void *user_data)
43 {
44         MonoDlMapping *mappings = (MonoDlMapping *) handle;
45         
46         for (;mappings->name; mappings++){
47                 if (strcmp (symbol, mappings->name) == 0){
48                         *err = g_strdup ("");
49                         return mappings->addr;
50                 }
51         }
52         *err = g_strdup ("Symbol not found");
53         return NULL;
54 }
55
56 /**
57  * mono_dl_register_library:
58 u * @name: Library name, this is the name used by the DllImport as the external library name
59  * @mappings: the mappings to register for P/Invoke.
60  *
61  * The mappings registered using this function are used as fallbacks if the dynamic linker 
62  * fails, or if the platform doesn't have a dynamic linker.
63  *
64  * Mappings is a pointer to the first element of an array of
65  * MonoDlMapping values.  The list must be terminated with both 
66  * the name and addr fields set to NULL.
67  *
68  * This is typically used like this:
69  * MonoDlMapping sample_library_mappings [] = {
70  *   { "CallMe", CallMe },
71  *   { NULL, NULL }
72  * };
73  *
74  * ...
75  * main ()
76  * {
77  *    ...
78  *    mono_dl_register_library ("sample", sample_library_mappings);
79  *    ...
80  * }
81  *
82  * Then the C# code can use this P/Invoke signature:
83  *
84  *      [DllImport ("sample")]
85  *      extern static int CallMe (int f);
86  */
87 void
88 mono_dl_register_library (const char *name, MonoDlMapping *mappings)
89 {
90         if (mono_dls == NULL){
91                 mono_dls = g_hash_table_new (g_str_hash, g_str_equal);
92                 mono_dl_fallback_register (dl_mapping_open, dl_mapping_symbol, NULL, NULL);
93         }
94         
95         g_hash_table_insert (mono_dls, g_strdup (name), mappings);
96 }
97