Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gdiplus.dll not found when using MonoKickstart on OSX

I have been using MonoKickstart to get our project - which is built on OpenTK - running on OSX. I got the program to work entirely, but once I removed my Mono.framework (well, actually renamed) the following error popped up:

[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: An exception was thrown by the type initializer for System.Drawing.GDIPlus ---> System.DllNotFoundException: gdiplus.dll
  at (wrapper managed-to-native) System.Drawing.GDIPlus:GdiplusStartup (ulong&,System.Drawing.GdiplusStartupInput&,System.Drawing.GdiplusStartupOutput&)
  at System.Drawing.GDIPlus..cctor () [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Drawing.Bitmap..ctor (System.String filename, Boolean useIcm) [0x00000] in <filename unknown>:0 
  at System.Drawing.Bitmap..ctor (System.String filename) [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) System.Drawing.Bitmap:.ctor (string)
 (...)

I have tried adding the "libgdiplus.0.dylib" from my mono installation to the included osx folder (where the mono dynamic libraries also sit) and the executable folder. Creating a dllmap also does not do anything, except for changing the filename in the error message.

I am using the sgen variant, so running in x64 can not be the issue (see also here for a discussion about this).

like image 938
Tom Avatar asked Mar 07 '15 14:03

Tom


1 Answers

This error means that mono was unable to locate a library that one of the classes you are trying to use needs.

To preserve compatibility with the .NET Framework, mono uses the same library names as windows. These names are mapped to linux library names using DllMaps.

(Substitute “.so” with “dylib” for MacOS X)

If a library location has not been explicitly specified in a DllMap entry in an application or assembly .config file, Mono will search for a library in a few places:

The directory where the referencing image was loaded from. In any place the system’s dynamic loader is configured to look for shared libraries. For example on Linux this is specified in the $LD_LIBRARY_PATH environment variable and the /etc/ld.so.conf file. On windows the $PATH environment variable is used, instead. The next step in resolving the issue is locating the file on your system.

$ find /usr -name libgdiplus.so /usr/local/lib/libgdiplus.so Aha! There it is. So why can’t mono find it?

By default in basically all distributions of linux the dynamic linker only creates a cache for files in /lib and /usr/lib. Since you have placed your library in /usr/local/lib, it does not know about it. You can verify this using the following command:

ldconfig -p |grep libgdiplus The command should produce no output, because it does not know about the file.

The correct way to fix this problem is to add /usr/local/lib as one of the paths that ldconfig indexes. To do this, add the path to /etc/ld.so.conf and run “ldconfig” as root, which will force the cache to be rebuilt.

The dynamic linker should now know about all the libraries in this path. You can verify this by typing the above command once again:

$ ldconfig -p |grep libgdiplus libgdiplus.so (libc6) => /usr/local/lib/libgdiplus.so Yay! Your application should now run properly.

NOTE: As mentioned above you can also set the $LD_LIBRARY_PATH environment variable to the path containing the library, but this is not as recomended because it can cause other problems and is more difficult to maintain.

For more Information please look at http://www.mono-project.com/docs/advanced/pinvoke/dllnotfoundexception/

like image 179
Steven Spyrka Avatar answered Nov 13 '22 12:11

Steven Spyrka