[Mono-devel-list] Proposal: Library Loading

Eran Sandler esandler at netvision.net.il
Wed Apr 14 04:04:21 EDT 2004


I'll outline what is and what was the assembly loading logic in .NET and
its early betas and lets see if we can borrow some of the ideas from
there.

In the early betas of .NET v1.0 when one wanted to dynamically load an
assembly and one did not specify its version it first searched in the
GAC (Global Assembly Cache) for the latest version of that assembly. 
If it did not find it, it will search in the app's directory and from
there go on to a predefined search path that you can define per an
application.

If you had a specific reference with a specific version, culture and
public key token, it will search for it in the GAC. If it will not find
it, it will search in the app's directory and so on.


In the release of .NET v1.0, Microsoft decided to make the assembly load
logic strickter. One cannot dynamically load things from the GAC unless
one specifies a specific version, culture and public key token.

If a new version of a certain assembly came out, a policy file (which is
actually a DLL which has a XML file embedded as a resource that
specifies the redirection from one version or a range of version to
another version) would control the redirection and even though an
application requested version 1.0, since there is a policy file, it will
actually get version 1.1, for example.


Since the GAC is the only place that Windows can handle versioning of
dynamically loaded files, perhaps we need a mechanism similar to the GAC
for DllImport.

This means that DllImport will have to include not just "foo", but
"foo-2" for example (or some other syntax, as long as it won't break the
DllImport signature). 

In this case we will specifically take libfoo.so.2 and only libfoo.so.2.

If a redirection is needed we can have some kind of an XML file that
will be located in a predefined place for a certain lib.

This is for the stricter people...




The other option is to assume the idea that was in the early .NET 1.0
betas. In this case, if someone specified only "foo", we can search for
the latest version available and use it. If someone specified a specific
version, like in the example I gave earlier, it will search for it, and
only it. If a redirection is needed we will have to find, as I said
above, a similar mechanism to GAC that will perform redirections.


There is also an option that instead of using policy files you can
declare a redirect in the application's config file (app.config) or in
the machine.config file. 

Therefore, for package installations, either the installer will update
the machine.config (if this is a shared library that simply have a fix
and a lot of apps use it) or a specific application app.config.
If we go for policy file like solution, the package installation can
simply put certain files in a certain place that will perform the
redirection.


What do you think?


Eran


On Wed, 2004-04-14 at 03:52, Jonathan Pryor wrote:
> This came up on #mono today in the context of Fedora and package
> management, so I figured I'd document the current idea for discussion
> and possible future implementation [1].
> 
> The Problem:
> 
> DllImport doesn't allow developers to specify which library version to
> load at runtime.  Thus, with code such as:
> 
> 	[DllImport ("foo")]
> 	private static extern void foo ();
> 
> Mono will attempt to load "libfoo.so" at runtime.
> 
> There are three problems with this:
> 
> 1.  What happens if there are multiple major versions of libfoo.so
>     installed: libfoo.so.1 and libfoo.so.2?  Which gets loaded?  At
>     present, whichever libfoo-devel package was installed, which may be
>     ABI-incompatible with what the assembly was written against.  Oops.
> 
> 2.  Ignoring (1), the user needs to have N MB of -devel packages
>     installed in order for Mono to find the .so file (as the .so file is
>     usually only present in the -devel packages).  N can be very large;
>     previously, I've heard of N > 50 MB.  Users will find this to be
>     unacceptable.
> 
> 3.  To avoid (2), the user can edit $prefix/mono/config, an XML file
>     which "maps" the DllImport library to the actual library to load. 
>     While this works, it is inelegant (the user has to edit XML, which
>     may scare some users), and is not extensible (what should happen
>     when a new library/assembly/RPM is installed?).
> 
> 
> The Proposed Solution:
> 
> Scrap $prefix/mono/config, and replace it with a $prefix/mono/config.d
> directory.  This directory would contain one file per DllImport "base"
> name, where a base name is the library name without the "lib" prefix and
> any suffix (".so", ".dll", .etc).
> 
> The syntax of the XML file could be:
> 
> 	<library>
> 		<dll import="DllImport Attribute Value" 
> 			target="actual library to load"
> 			version="version .NET assembly targets"/>
> 	</library>
> 
> For example, the C library would have an entry in
> $prefix/mono/config.d/c.xml, which the contents:
> 
> 	<library>
> 		<dll import="libc" 
> 			target="libc.so"
> 			version="6" />
> 	</library>
> 
> The version attribute is present to solve problem (1), and would contain
> the major and optional minor version number of the library to load. 
> Mono's library loading logic would thus need to search for the
> ${target}.${version} library in the standard locations (LD_LIBRARY_PATH,
> /etc/ld.so.conf, /usr/lib, /lib), with intelligent fallback handling
> (e.g. if @version is 1.2, and ${target}.1.2 isn't present, but
> ${target}.1 is, then ${target}.1 should be loaded).
> 
> Benefits:
> 
> The "one file per base library name" ensures that only one package (RPM,
> etc.) will attempt to "own" a particular library, so we don't have
> multiple packages attempting to "own" the GTK+ libraries.
> 
> The version number attribute benefits were mentioned above.
> 
> Future packages can install files into $prefix/mono/config.d as part of
> their install, ensuring that any native libraries they require will be
> found by Mono, simplifying package maintenance.
> 
> The one potentially troubling part is the duplication between the file
> name and the /library/dll/@import attribute value.
> 
> Thoughts?
> 
>  - Jon
> 
> [1] Alas, I'm not implementing this.  I plead lack of time. :-(
> 
> 
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list




More information about the Mono-devel-list mailing list