[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