JacePriester's picture

OpenTK::GLControl on Win7/VS2008 trying to load libX11

I didn't have this issue until I attempted to use GLControl. I'm using C++/CLI with VS2008 on Win7 64-bit. My GL control class is declared as follows:

public ref class PhotoEditor:public OpenTK::GLControl

and the program errors out when the constructor is called with the following (I kept clicking Continue):

A first chance exception of type 'System.DllNotFoundException' occurred in OpenTK.dll

Additional information: Unable to load DLL 'libX11': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

A first chance exception of type 'System.TypeInitializationException' occurred in OpenTK.dll

Additional information: The type initializer for 'OpenTK.Platform.X11.API' threw an exception.

A first chance exception of type 'System.DllNotFoundException' occurred in OpenTK.dll

Additional information: Unable to load DLL 'libEGL.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

Thank you for any help you can provide.


Comments

Comment viewing options

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

Maybe this will narrow it down a little. See the following line:

MessageBox::Show(OpenTK::Configuration::RunningOnWindows.ToString());

Yep, that causes it to try to load libX11.

Btw, I'm using the 10-6-2010 release.

the Fiddler's picture

These exceptions are a normal part of the OpenTK initialization process. OpenTK is trying to discover the capabilities of the platform (is EGL available? Is an X server available?) - the exceptions are thrown and caught internally and do not indicate an error.

Visual Studio by default uses "Just my code" debugging, which does not break on exceptions thrown and caught in 3rd-party dlls. Make sure you have that option enabled or, if you need to keep it disabled, add those exceptions to your exception ignore list.

c2woody's picture

Why is X-Server detection required under windows? It was mentioned elsewhere (can't find it now) that these exceptions are easily avoidable and make debugging in all-exceptions-break-mode a lot easier.

the Fiddler's picture

It is possible to run an X-server on Windows (someone was asking about that a few months ago). Even if you removed that part, you'd still get an exception for EGL so it wouldn't solve the issue.

Ctrl-D, E brings up the "Exceptions" window that lists all known exceptions. Each exception has two settings: break when "thrown" and break when "user-unhandled". Locate the "DllNotFoundException" and make sure both checkboxes are disabled.

Edit: I can't recall that we found any way to avoid those exceptions. It would help if you could dig up a link.

c2woody's picture
Quote:

you'd still get an exception for EGL so it wouldn't solve the issue.

It should be possible to remove 2 of 3 of the exceptions (don't know if EGL can be detected without using an exception block). The idea was to call the code parts that reference X-Server detection only on non-windows systems.

Quote:

Each exception has two settings: break when "thrown" and break when "user-unhandled". Locate the "DllNotFoundException" and make sure both checkboxes are disabled.

I'm aware of that but usually the "thrown" is toggled for all CLR exceptions and looking up single exceptions to disable just for that complicates the quick on/off process.

c2woody's picture
the Fiddler wrote:

I can't recall that we found any way to avoid those exceptions. It would help if you could dig up a link.

http://www.opentk.com/node/1775

Greggor01's picture

Has anyone figured out what to do about this? It seems to be causing quite a few issues in my applications. I can't make any calls to OpenTK without causing a System.TypeInitialization Exception.

c2woody's picture
Greggor01 wrote:

Has anyone figured out what to do about this? It seems to be causing quite a few issues in my applications. I can't make any calls to OpenTK without causing a System.TypeInitialization Exception.

The exceptions this thread is about are all fully handled so in normal operation (break on exception occurrance is disabled, which is the default) so they should not interfere with your application.

ebnf's picture

I've added a hack around this issue in my code by adding a new INativeLibrary interface loaded by IPlatformFactory that knows how to LoadLibrary/FreeLibrary/GetProcAddress for the platform then checks for the presence of these components before trying anything with a DllImport.

Index: INativeFontListing.cs
===================================================================
--- INativeFontListing.cs	(revision 0)
+++ INativeFontListing.cs	(revision 0)
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Diagnostics.Contracts;
+
+namespace OpenTK.Platform {
+	/// <summary>
+	/// Creates a new native font listing service.
+	/// </summary>
+	[ContractClass (typeof (ContractForINativeFontListing))]
+	public interface INativeFontListing {
+		/// <summary>
+		/// Lists the paths to all system fonts.
+		/// </summary>
+		/// <returns></returns>
+		IEnumerable<Uri> GetSystemFonts ();
+
+		/// <summary>
+		/// Lists the paths to all installed fonts.
+		/// </summary>
+		/// <returns></returns>
+		IEnumerable<Uri> GetInstalledFonts ();
+	}
+
+	[ContractClassFor (typeof (INativeFontListing))]
+	internal abstract class ContractForINativeFontListing : INativeFontListing {
+		#region INativeFontListing Members
+
+		public Uri GetFontPath (string font)
+		{
+			Contract.Requires<ArgumentNullException> (font != null, "font");
+			Contract.Ensures (Contract.Result<Uri> () != null);
+
+			throw new NotImplementedException ();
+		}
+
+		public IEnumerable<Uri> GetSystemFonts ()
+		{
+			Contract.Ensures (Contract.Result<IEnumerable<Uri>> () != null);
+			Contract.Ensures (Contract.ForAll (Contract.Result<IEnumerable<Uri>> (), uri => uri != null));
+
+			throw new NotImplementedException ();
+		}
+
+		public IEnumerable<Uri> GetInstalledFonts ()
+		{
+			Contract.Ensures (Contract.Result<IEnumerable<Uri>> () != null);
+			Contract.Ensures (Contract.ForAll (Contract.Result<IEnumerable<Uri>> (), uri => uri != null));
+
+			throw new NotImplementedException ();
+		}
+
+		#endregion
+	}
+}
Index: INativeLibrary.cs
===================================================================
--- INativeLibrary.cs	(revision 0)
+++ INativeLibrary.cs	(revision 0)
@@ -0,0 +1,34 @@
+using System;
+using System.Diagnostics.Contracts;
+
+namespace OpenTK.Platform
+{
+	/// <summary>
+	/// Creates a native dynamic shared library loader.
+	/// </summary>
+    [ContractClass(typeof(ContractForINativeLibrary))]
+    public interface INativeLibrary : IDisposable
+    {
+		/// <summary>
+		/// Fetches the address of the named function entry point.
+		/// </summary>
+		/// <param name="functionName"></param>
+		/// <returns></returns>
+        IntPtr GetProcAddress(string functionName);        
+    }
+
+    [ContractClassFor(typeof(INativeLibrary))]
+    internal abstract class ContractForINativeLibrary : INativeLibrary
+    {
+        public IntPtr GetProcAddress(string functionName)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Dispose()
+        {
+            throw new NotImplementedException();
+        }
+    }
+
+}
Index: MacOS/MacOSFactory.cs
===================================================================
--- MacOS/MacOSFactory.cs	(revision 2807)
+++ MacOS/MacOSFactory.cs	(working copy)
@@ -75,6 +75,41 @@
             throw new NotImplementedException();
         }
 
+		public virtual INativeLibrary LoadLibrary (string libraryName)
+		{
+			IntPtr handle = Carbon.API.dlopen (libraryName, 0);
+			return _library = (handle == IntPtr.Zero) ? null : new MacOSLibrary (libraryName, handle);
+		}
+
+		#endregion
+
+		static MacOSLibrary _library;
+		~MacOSFactory ()
+		{
+			Dispose (false);
+		}
+
+		public void Dispose ()
+		{
+			Dispose (true);
+			GC.SuppressFinalize (this);
+		}
+		private void Dispose (bool disposing)
+		{
+			if (_library != null) {
+				_library.Dispose ();
+				_library = null;
+			}
+		}
+
+		#region IPlatformFactory Members
+
+
+		public INativeFontListing LoadFonts ()
+		{
+			throw new NotImplementedException ();
+		}
+
         #endregion
     }
 }
Index: Windows/WinFactory.cs
===================================================================
--- Windows/WinFactory.cs	(revision 2807)
+++ Windows/WinFactory.cs	(working copy)
@@ -81,6 +81,44 @@
                 return new WMInput(null);
         }
 
+        [SecuritySafeCritical]
+        public virtual INativeLibrary LoadLibrary(string libraryName)
+        {
+            IntPtr handle = Functions.LoadLibrary(libraryName);
+            return _library = (handle == IntPtr.Zero) ? null : new WinLibrary(libraryName, handle);
+        }
+
         #endregion
+
+        static WinLibrary _library;
+
+        ~WinFactory()
+        {
+            Dispose(false);
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+        private void Dispose(bool disposing)
+        {
+            if (_library != null)
+            {
+                _library.Dispose();
+                _library = null;
+            }
+        }
+
+		#region IPlatformFactory Members
+
+
+		public INativeFontListing LoadFonts ()
+		{
+			return new WinFontListing ();
+		}
+
+        #endregion
     }
 }
Index: X11/X11Factory.cs
===================================================================
--- X11/X11Factory.cs	(revision 2807)
+++ X11/X11Factory.cs	(working copy)
@@ -83,6 +83,41 @@
             throw new NotImplementedException();
         }
 
+		public virtual INativeLibrary LoadLibrary (string libraryName)
+		{
+			IntPtr handle = Functions.dlopen (libraryName, 0);
+			return _x11Library = (handle == IntPtr.Zero) ? null : new X11Library (libraryName, handle);
+		}
+
+		#endregion
+
+		static X11Library _x11Library;
+
+		~X11Factory ()
+		{
+			Dispose (false);
+		}
+
+		public void Dispose ()
+		{
+			Dispose (true);
+			GC.SuppressFinalize (this);
+		}
+		private void Dispose (bool disposing)
+		{
+			if (_x11Library != null) {
+				_x11Library.Dispose ();
+			}
+		}
+
+		#region IPlatformFactory Members
+
+
+		public INativeFontListing LoadFonts ()
+		{
+			throw new NotImplementedException ();
+		}
+
         #endregion
     }
 }
the Fiddler's picture

Thanks, this should indeed work.