Hi Andy,

I believe you have your DLL in the GAC correctly. Let's say you built your DLL at c:\work\lib.dll and added it to the GAC. You should now be able to to compile a program that references the DLL (say c:\test\test.exe), and you should be able to run that program and it will bind to the copy of lib.dll in the GAC rather than the compile-time location. See below for a technique to verify this.

Referencing GAC DLLs from FSI is a slightly more complicated story. FSI needs a referenced DLL for two very different purposes

  • a "reference" copy of the DLL (used for type checking and codegen)
  • a "runtime" copy of the DLL (used when running generated code).

This means you simply need to

  1. Add your DLL to the GAC as you have done
  2. Also specify a #r or -r to a physical "reference" copy of the DLL (e.g. a physical copy in the place where you installed it). The resolution of -r etc. does NOT search the GAC. (It turns out you can give a -r to the actual copy of the file in the GAC, though that's not really recommended, since it's not really a "public" location)

Note that for non-GAC DLLs the "reference" and "runtime" DLLs are precisely the same file. As of 1.1.13.8 for GAC DLLs they will normally be <i>different<i> physical copies of the same file (one in the GAC, one at a known path). <i>This means that as of 1.1.13.8 you need to ensure the consistency between the "reference" and "runtime" copies of the DLL, as they are not actually the same file<i>. This simply means the GAC DLL must be up-to-date. This is only potentially a problem on the machine where you're developing the DLL: an installer would typically install the same bits to the GAC and put a "reference" copy of the DLL under some known path such as "c:\program files\MyTool\MyLibrary.dll". Maintaining this consistency property is obviously a bit of a pain (it's easy to forget to update the GAC). We'll work on fixing this, by ensuring FSI loads exactly the copy of the DLL referenced using "-r". To put this another way, as of 1.1.13.8 when FSI does a "runtime bind" it will typically be to the copy of the DLL in the GAC <i>even if this is different to the "reference" copy found by giving an explicit path or by searching along the -I search paths<i>. For example if I make a strongly-named library "empty.dll" in "C:\", add it to the GAC and reference it using <code lang=fsharp>#r @"C:\empty.dll";;</code> then the "compile-time" copy of the DLL is unsurprisingly "C:\empty.dll". However as of 1.1.13.8 the behaviour of FSI is that <i>the runtime bind to the DLL is to the copy in the GAC<i>. To check this you can use use the output of a debugger such as windbg.exe to see which DLL really gets loaded, e.g.: <code lang=fsharp> ... ModLoad: 03a50000 03a58000 C:\WINDOWS\assembly\GAC_MSIL\empty\0.0.0.0__a19089b1c74d0809\empty.dll </code> This is not actually a problem if you ensure the consistency of the DLL in the GAC with the one referenced by "-r" or "#r". Don

By on 12/16/2006 6:40 AM ()

It would be really nice if we could easily reference a dll in the GAC. How about creating a System.Uri for a System.Reflection.AssemblyName? Examples may look like this:

#r "gac://com.microsoft.crypto/"
#r "gac://com.microsoft.crypto/?Version=1.0.0.0"
#r "gac://com.microsoft.crypto/?Culture=en&PublicKeyToken=a5d015c7d5a0b012&Version=1.0.0.0"

You would then reference the assembly name using the "gac://" URI scheme. Right now, it only supports the "file://" scheme implicitly.

WDYT?

Cameron

By on 8/7/2008 12:39 AM ()

I think adding a new naming scheme for assembly references would just add confusion.

But it could be doable to use use the fully qualified assembly name with the #r command, and have the runtime figure out how to load it.

//huusom

By on 8/8/2008 2:39 PM ()

offtop: Sometimes ago I was wandering about extending .NET's fusion process ( here may be mistake in name :) ) to automatically search and load latest libraries from the Internet.

By on 8/7/2008 6:24 AM ()

Thanks Don, as you suggest the DLL was installed properly in the GAC and EXE's could find it. My mistake was thinking that once installed in the GAC "namespaces" became available. It makes more sense the way you describe it.

Is it actually possible to write an API which becomes "standard" like the System and Microsoft namespaces thus not requiring the "-r" refererence during compilation? Alternatively, would you consider adding FSC_INCLUDE and FSC_LIBRARY environment variables for fsc/fsi?

Cheers,

Andy

By on 12/16/2006 6:28 PM ()

There is no such thing as a standard name space, the F# compiler simply reference a number of .dlls by default (this is also the behavior of the C# and VB.NET compilers). I believe these are:

mscorlib.dll
System.dll
System.Data.dll
System.Drawing.dll
System.Web.dll
System.Web.Services.dll
System.Windows.Forms.dll
System.XML.dll
fslib.dll
mllib.dll

I think these are listed in the manual some where, but I had a quick look and couldn't find it.

If you not want to these library's to be reference you can use the compilers --no-framework flag for the .NET framework ones and --no-mllib to get rid of the mllib.dll.

You may notice how there's no Microsoft.Win32.dll, but this available as standard. It is because this name is actually split between mscorlib.dll and System.dll, it's important to note there's no actual relation between the name of a .dll and the names it contains.

Cheers,
Rob

By on 12/16/2006 11:38 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper