[Mono-dev] BSTR Marshalling in Mono
Paolo Molaro
lupus at ximian.com
Fri Jan 11 13:03:59 EST 2008
On 01/08/08 Jonathan Chambers wrote:
> Here is the first attempt at a patch. Nothing is changed with the
> default configuration. Things are controlled via an environment variable
> (MONO_COM), and extensible using the dllmap in the config file. The only
> other current configuration is MONO_MS, which supports Mainsoft COM
> components. If this looks acceptable, I will cleanup any issues and document
> the environment variable.
Since we hardcode the functions, I wonder if this should really be
configurable.
> Index: metadata/loader.h
> ===================================================================
> --- metadata/loader.h (revision 92458)
> +++ metadata/loader.h (working copy)
> @@ -62,6 +62,9 @@
> void
> mono_dllmap_insert (MonoImage *assembly, const char *dll, const char *func, const char *tdll, const char *tfunc);
>
> +int
> +mono_dllmap_lookup (MonoImage *assembly, const char *dll, const char* func, const char **rdll, const char **rfunc);
IIF we expose this, it should be a MONO_INTERNAL function in a private
header.
> Index: metadata/marshal.c
> ===================================================================
> --- metadata/marshal.c (revision 92458)
> +++ metadata/marshal.c (working copy)
> mono_string_to_bstr (MonoString *string_obj)
> {
> @@ -1082,19 +1094,60 @@
> return NULL;
> return SysAllocStringLen (mono_string_chars (string_obj), mono_string_length (string_obj));
> #else
> - int slen = mono_string_length (string_obj);
> - char *ret = g_malloc (slen * 2 + 4 + 2);
> - if (ret == NULL)
> - return NULL;
> - memcpy (ret + 4, mono_string_chars (string_obj), slen * 2);
> - * ((guint32 *) ret) = slen * 2;
> - ret [4 + slen * 2] = 0;
> - ret [5 + slen * 2] = 0;
> + if (com_provider == MONO_COM_DEFAULT) {
> + int slen = mono_string_length (string_obj);
> + char *ret = g_malloc (slen * 2 + 4 + 2);
> + if (ret == NULL)
> + return NULL;
> + memcpy (ret + 4, mono_string_chars (string_obj), slen * 2);
> + * ((guint32 *) ret) = slen;
> + ret [4 + slen * 2] = 0;
> + ret [5 + slen * 2] = 0;
>
> - return ret + 4;
> + return ret + 4;
> + }
> + else if (com_provider == MONO_COM_MS) {
The else goes into the same line as the closing }.
> + char *error_msg;
> + gpointer ret = NULL;
> + gunichar* str = NULL;
> + guint32 len;
> + MonoDl *module = NULL;
> + SysAllocStringLenFunc pSysAllocString = NULL;
> + const char* scope = "liboleaut32.so";
> + const char* import = "SysAllocStringLen";
> + const char* new_scope = NULL;
> + const char* new_import = NULL;
> + if (mono_dllmap_lookup (mono_defaults.corlib, scope, import, &new_scope, &new_import)) {
> + scope = new_scope;
> + import = new_import;
> + }
> + module = mono_dl_open(scope, MONO_DL_LAZY, &error_msg);
> + if (error_msg) {
> + g_warning ("Error loading COM support library '%s': %s", scope, error_msg);
> + g_assert_not_reached ();
> + return NULL;
> + }
> + error_msg = mono_dl_symbol (module, import, (gpointer*)&pSysAllocString);
> + if (error_msg) {
> + g_warning ("Error loading entry point '%s' in COM support library '%s': %s", import, scope, error_msg);
> + g_assert_not_reached ();
> + return NULL;
> + }
Please put this code into its own function and share it with
SysStringLen and SysFreeString: the tree lookups should be done at the
same time.
Thanks!
lupus
--
-----------------------------------------------------------------
lupus at debian.org debian/rules
lupus at ximian.com Monkeys do it better
More information about the Mono-devel-list
mailing list