plugins/mono/loader/mono-helper.c

changeset 14253
b63ebf84c42b
parent 14252
d10dda2777a9
child 14254
77edc7a6191a
equal deleted inserted replaced
14252:d10dda2777a9 14253:b63ebf84c42b
1 /*
2 * Mono Plugin Loader
3 *
4 * -- Thanks to the perl plugin loader for all the great tips ;-)
5 *
6 * Eoin Coffey
7 */
8
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12
13 #include <glib.h>
14 #include <string.h>
15 #include "mono-helper.h"
16 #include "mono-glue.h"
17 #include "value.h"
18 #include "debug.h"
19
20 static gboolean _runtime_active = FALSE;
21
22 gboolean ml_init()
23 {
24 MonoDomain *d;
25
26 g_return_val_if_fail(_runtime_active == FALSE, TRUE);
27
28 d = mono_jit_init("gaim");
29
30 if (!d) {
31 ml_set_domain(NULL);
32 return FALSE;
33 }
34
35 ml_set_domain(d);
36
37 ml_init_internal_calls();
38
39 _runtime_active = TRUE;
40
41 return TRUE;
42 }
43
44 void ml_uninit()
45 {
46 g_return_if_fail(_runtime_active == TRUE);
47
48 mono_jit_cleanup(ml_get_domain());
49
50 ml_set_domain(NULL);
51
52 _runtime_active = FALSE;
53 }
54
55 MonoObject* ml_delegate_invoke(MonoObject *method, void **params)
56 {
57 MonoObject *ret, *exception;
58
59 ret = mono_runtime_delegate_invoke(method, params, &exception);
60 if (exception) {
61 gaim_debug(GAIM_DEBUG_ERROR, "mono", "caught exception: %s\n", mono_class_get_name(mono_object_get_class(exception)));
62 }
63
64 return ret;
65 }
66
67 MonoObject* ml_invoke(MonoMethod *method, void *obj, void **params)
68 {
69 MonoObject *ret, *exception;
70
71 ret = mono_runtime_invoke(method, obj, params, &exception);
72 if (exception) {
73 gaim_debug(GAIM_DEBUG_ERROR, "mono", "caught exception: %s\n", mono_class_get_name(mono_object_get_class(exception)));
74 }
75
76 return ret;
77 }
78
79 MonoClass* ml_find_plugin_class(MonoImage *image)
80 {
81 MonoClass *klass, *pklass = NULL;
82 int i, total;
83
84 total = mono_image_get_table_rows (image, MONO_TABLE_TYPEDEF);
85 for (i = 1; i <= total; ++i) {
86 klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | i);
87 pklass = mono_class_get_parent(klass);
88 if (pklass)
89 if (strcmp("GaimPlugin", mono_class_get_name(pklass)) == 0)
90 return klass;
91 }
92
93 return NULL;
94 }
95
96 void ml_set_prop_string(MonoObject *obj, char *field, char *data)
97 {
98 MonoClass *klass;
99 MonoProperty *prop;
100 MonoString *str;
101 gpointer args[1];
102
103 klass = mono_object_get_class(obj);
104
105 prop = mono_class_get_property_from_name(klass, field);
106
107 str = mono_string_new(ml_get_domain(), data);
108
109 args[0] = str;
110
111 mono_property_set_value(prop, obj, args, NULL);
112 }
113
114 gchar* ml_get_prop_string(MonoObject *obj, char *field)
115 {
116 MonoClass *klass;
117 MonoProperty *prop;
118 MonoString *str;
119
120 klass = mono_object_get_class(obj);
121
122 prop = mono_class_get_property_from_name(klass, field);
123
124 str = (MonoString*)mono_property_get_value(prop, obj, NULL, NULL);
125
126 return mono_string_to_utf8(str);
127 }
128
129 gboolean ml_is_api_dll(MonoImage *image)
130 {
131 MonoClass *klass;
132 int i, total;
133
134 total = mono_image_get_table_rows (image, MONO_TABLE_TYPEDEF);
135 for (i = 1; i <= total; ++i) {
136 klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | i);
137 if (strcmp(mono_class_get_name(klass), "Debug") == 0)
138 if (strcmp(mono_class_get_namespace(klass), "Gaim") == 0) {
139 ml_set_api_image(image);
140 return TRUE;
141 }
142 }
143
144 return FALSE;
145 }
146
147 MonoObject* ml_object_from_gaim_type(GaimType type, gpointer data)
148 {
149 return NULL;
150 }
151
152 MonoObject* ml_object_from_gaim_subtype(GaimSubType type, gpointer data)
153 {
154 MonoObject *obj = NULL;
155
156 switch (type) {
157 case GAIM_SUBTYPE_BLIST_BUDDY:
158 obj = gaim_blist_build_buddy_object(data);
159 break;
160 case GAIM_SUBTYPE_STATUS:
161 obj = gaim_status_build_status_object(data);
162 break;
163 default:
164 break;
165 }
166
167 return obj;
168 }
169
170 MonoObject* ml_create_api_object(char *class_name)
171 {
172 MonoObject *obj = NULL;
173 MonoClass *klass = NULL;
174
175 klass = mono_class_from_name(ml_get_api_image(), "Gaim", class_name);
176 if (!klass) {
177 gaim_debug(GAIM_DEBUG_FATAL, "mono", "couldn't find the '%s' class\n", class_name);
178 return NULL;
179 }
180
181 obj = mono_object_new(ml_get_domain(), klass);
182 if (!obj) {
183 gaim_debug(GAIM_DEBUG_FATAL, "mono", "couldn't create the object from class '%s'\n", class_name);
184 return NULL;
185 }
186
187 mono_runtime_object_init(obj);
188
189 return obj;
190 }
191
192 static MonoDomain *_domain = NULL;
193
194 MonoDomain* ml_get_domain(void)
195 {
196 return _domain;
197 }
198
199 void ml_set_domain(MonoDomain *d)
200 {
201 _domain = d;
202 }
203
204 static MonoImage *_api_image = NULL;
205
206 void ml_set_api_image(MonoImage *image)
207 {
208 _api_image = image;
209 }
210
211 MonoImage* ml_get_api_image()
212 {
213 return _api_image;
214 }
215
216 void ml_init_internal_calls(void)
217 {
218 mono_add_internal_call("Gaim.Debug::_debug", gaim_debug_glue);
219 mono_add_internal_call("Gaim.Signal::_connect", gaim_signal_connect_glue);
220 mono_add_internal_call("Gaim.BuddyList::_get_handle", gaim_blist_get_handle_glue);
221 }
222
223 static GHashTable *plugins_hash = NULL;
224
225 void ml_add_plugin(GaimMonoPlugin *plugin)
226 {
227 if (!plugins_hash)
228 plugins_hash = g_hash_table_new(NULL, NULL);
229
230 g_hash_table_insert(plugins_hash, plugin->klass, plugin);
231 }
232
233 gboolean ml_remove_plugin(GaimMonoPlugin *plugin)
234 {
235 return g_hash_table_remove(plugins_hash, plugin->klass);
236 }
237
238 gpointer ml_find_plugin(GaimMonoPlugin *plugin)
239 {
240 return g_hash_table_lookup(plugins_hash, plugin->klass);
241 }
242
243 gpointer ml_find_plugin_by_class(MonoClass *klass)
244 {
245 return g_hash_table_lookup(plugins_hash, klass);
246 }
247
248 GHashTable* ml_get_plugin_hash()
249 {
250 return plugins_hash;
251 }

mercurial