So I have a C# program that I'm making in Visual Studio Mac 2019. It uses the SFML.Net framework which depends on a dynamic library: libcsfml-graphics.2.5.0.dylib
. Internally, the framework has a method called sfRenderWindow_createUnicode(...)
. This method uses a DLLImport
for CSFML.graphics
. If I run the program in Visual Studio, I get a DllNotFoundException
with message csfml-graphics
.
In my global config
file for Mono, I have a DLL Mapping:
<dllmap dll="csfml-graphics" target="libcsfml-graphics.2.5.0.dylib" />
After adding that, if I run my program in Visual Studio, I still get a DllNotFoundException
. However, the message now says libcsfml-graphics.2.5.0.dylib
. So it's looking for the right library but can't find it? The .dylib
file is in the same folder as the .exe
.
The weird part is I can run the program from the terminal like so:
MONO_LOG_LEVEL=debug MONO_LOG_MASK=dll mono hello-csharp.exe > log.txt
The log.txt
file contains the following lines:
Mono: DllImport attempting to load: 'libcsfml-graphics.2.5.0.dylib'.
Mono: DllImport loaded library '/Users/rutvik/Desktop/hello-csharp/hello-csharp/bin/Debug/libcsfml-graphics.2.5.0.dylib'.
Mono: DllImport searching in: 'libcsfml-graphics.2.5.0.dylib' ('/Users/rutvik/Desktop/hello-csharp/hello-csharp/bin/Debug/libcsfml-graphics.2.5.0.dylib').
Mono: Searching for 'sfRenderWindow_createUnicode'.
Mono: Probing 'sfRenderWindow_createUnicode'.
Mono: Found as 'sfRenderWindow_createUnicode'.
So it can find the .dylib
for some reason. What is Visual Studio Mac doing differently? And how do I configure it to make it work?
For reference, here is otool -L
run against libcsfml-graphics.2.5.0.dylib
:
libcsfml-graphics.2.5.0.dylib:
libcsfml-graphics.2.5.dylib (compatibility version 2.5.0, current version 2.5.0)
@rpath/sfml-graphics.framework/Versions/2.5.1/sfml-graphics (compatibility version 2.5.0, current version 2.5.1)
@rpath/sfml-window.framework/Versions/2.5.1/sfml-window (compatibility version 2.5.0, current version 2.5.1)
@rpath/sfml-system.framework/Versions/2.5.1/sfml-system (compatibility version 2.5.0, current version 2.5.1)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)
WHAT WORKED IN THE END:
Just to summarize, I put all the .dylib
files in /usr/local/lib
. The trick was to set the platform target to x64
as specified in the accepted answer. The DYLD_LIBRARY_PATH
environment actually turned out to be not needed at all. And the .dylib
files do not have to be in the same folder as the .exe
.
Now both running from Visual Studio and running with mono
in the terminal yield identical results.
Hooray!
1) Make sure your Platform Target
matches your ABI type (x32 or x64 bit):
VS4M will launch the 32-bit Mono version by default as most project targets default to x32
. Of course this does not matter if you are producing "fat" dylibs.
2) Set DYLD_LIBRARY_PATH
in your Run Configuration
to match your dylib location:
re: https://www.mono-project.com/docs/advanced/pinvoke/#macos-framework-and-dylib-search-path