pjcozzi's picture

OpenTK.dll.config

Hi,

I wanted to confirm that OpenTK.dll.config is no longer required for running on Linux and Mac. I tested on Linux (Ubuntu 10.4) and it worked without the .config file, but I don't have immediate access to a Mac for testing, so I wanted to double check.

Regards,
Patrick


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

This doesn't sound right. I haven't changed anything that would affect this - maybe Mono is shipping the necessary dll maps on its own?

I just tested and I can indeed run OpenGL applications without a dll.config file. However, OpenAL applications still fail with a DllNotFoundException on openal32.dll.

Edit: this might also mean that glXGetProcAddress succeeds for all entry points, and DllImports aren't used at all. In this case, Mac OS X should work, too. However, OpenAL will still fail because it uses DllImports exclusively.

pjcozzi's picture

For OpenGL only, do you think it is safe to not include the dll.config file? If it is needed, I am ok including it, but if we can get away without it, I'd rather have the cleaner deployment.

Regards,
Patrick

Virtual Globe and Terrain Rendering Blog

the Fiddler's picture

Deploying without OpenTK.dll.config is neither tested nor supported at this point. It may work on some configurations but it *will* cause problems on others (this is the first time I've actually seen OpenTK working without this file).

There is one detail that might make deployment simpler: Mono will load dll.config files placed under ~/.mono/[dllname] (*) - this means you should be able add the dll.config as an embedded resource and write it to disk on startup.

(*) I'm pretty sure this is the correct path but it's been some time since I last tested this so I might be wrong.

Edit: I'm sure this used to work but I cannot find any reference in the Mono documentation...

the Fiddler's picture

Apparently, the correct location is: ~/.mono/assemblies/[assembly]/[assembly.ext].config

I will try to see whether this can be handled by OpenTK automatically.

the Fiddler's picture

Ok, this is impossible to handle inside OpenTK, since OpenTK.dll.config file is parsed at the same time as the dll. However, you should be able to embed the file as a resource and write it to ~/.mono/assemblies/OpenTK before OpenTK.dll is loaded. Something like the following code might do the trick:

namespace Foo
    class MainClass
    {
        public static void Main()
        {
             WriteConfigFile();
 
             using (var game = new GameWindow())
             {
                  game.Run();
             }
        }
 
        // Creates path on disk if it doesn't already exist
        static void CreatePath(string path)
        {
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
        }
 
        // Write OpenTK.dll.config to disk when running on non-Windows platforms.
        // Mono loads config files from ~/.mono/assemblies/OpenTK, automatically.
        static void WriteConfigFile()
        {
            Debug.Write("Writing config file ");
            string name = null;
            string monopath = null;
            string asmpath = null;
            string outpath = null;
            string file_old = null;
            string file = null;
 
            try
            {
                Assembly asm = Assembly.GetAssembly(typeof(Configuration));
                name = asm.GetName().Name; // In case someone embeds OpenTK into another dll.
                monopath = Path.Combine(
                    Environment.GetFolderPath(Environment.SpecialFolder.Personal),
                    ".mono");
                asmpath = Path.Combine(monopath, "assemblies");
                outpath = Path.Combine(asmpath, name);
                file_old = Path.ChangeExtension(name, "dll.config"); // For mono version prior to 1.9
                file = Path.ChangeExtension(name, "config"); // For mono 1.9 and higher
                Debug.Print("to {0}/{1}.", outpath, file);
                CreatePath(monopath);
                CreatePath(asmpath);
                CreatePath(outpath);
 
                Debug.Print("Loading embedded config.");
                // Note: the resource name and namespace are hardcoded.
                // This will fail if someone recompiles OpenTK with a different namespace
                // (not *our* problem, though).
                Stream str = asm.GetManifestResourceStream("OpenTK.OpenTK.dll.config");
                if (str != null)
                {
                    using (str)
                    {
                        byte[] buffer = new byte[str.Length];
                        str.Read(buffer, 0, buffer.Length);
                        string config = System.Text.UnicodeEncoding.Default.GetString(buffer);
                        System.IO.File.WriteAllText(Path.Combine(outpath, file), config);
                        System.IO.File.WriteAllText(Path.Combine(outpath, file_old), config);
                    }
                    Debug.Print("Success!");
                }
                else
                {
                    Debug.Print("[Warning] Failed, embedded config not found.");
                }
            }
            catch (Exception e)
            {
                Debug.Print("[Warning] Failed to write {0} to \"{1}\". Error: {2}", file, outpath, e);
            }
        }
    }
}
pjcozzi's picture

Thanks for taking a look at this. I'll let you know how it goes and if we come up with any other alternatives.

Thanks,
Patrick
Virtual Globe and Terrain Rendering Blog