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
Related
I'm trying to get a Xamarin Forms solution to build from the command line as part of a build script using the command dotnet build <solution.sln>. Most of the projects in the solution build; however, two projects fail with this error message: error MSB6006: "csc.exe" exited with code 1.(on Ubuntu) and error MSB6006: "csc.exe" exited with code 8. (on Mac).
I have running Ubuntu 18.04 (using Windows subsystem for Linux) and MacOS 10.13.6 on separate machines.
I have also tried to run dotnet build <solution.sln> from the windows command line which prints out this error message instead:
error MSB4062: The "XamarinLive.Build.XamarinLiveTask" task could not be loaded from the assembly C:\Users\Jason.nuget\packages\livexaml\2.1.22\build\XamarinLive.Build.dll. Could not load file or assembly 'Microsoft.Build.Utilities.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified. Confirm that the declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
However, the solution works and builds fine from within VS2017 (Version 15.9.7). I've tried scouring the binary log that is generated but I can't make much sense of it and there doesn't seem to be any obvious errors (on Ubuntu & Mac). Could the windows error message be related in some way?
The projects that are failing target netstandard 2.0 (The same as the projects that do build). The version returned by dotnet --version on all 3 environments is 2.1.504.
Any help would be greatly appreciated.
You need to use msbuild.exe instead of dotnet
build
for this situation.
msbuild.exe runs on full framework while dotnet buildruns on .NET Core, and most of the build tasks don't support that.
When you build them in VS,it actually calls the msbuild.exe to build the solution.So you can build it well by developer command prompt since it also calls the msbuild.exe.
For vs2017, you can find it in C:\Program Files (x86)\Microsoft Visual Studio\2017\Edition\MSBuild\15.0\Bin.
More details see Martin's answer from this similar issue. Thanks to his detailed description!
There are some c++ projects(vcxproj) in my solution those really interop projects.
All was fine until I tried to re-build them for .net v3.5 (they initially target .net v4.5)
I changed the version string to "v3.5" in the project files, changed the path for ilasm to
‘C:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe’
and all looks fine.
I built these projects, made a msi package and tried to install it, but got this error:
Assembly Install: Failing with hr=8013141a
Assembly Error:Strong name signature verification failed for assembly '%1'. The assembly may have been tampered with, or it was delay signed but not fully signed with the correct private key.
Product: MY_PROJECT -- Error 1937. An error occurred during the installation of assembly 'MY_PROJECT.Interop,Version="5.3.0.0",Culture="neutral", PublicKeyToken="0DC6B9046BBF1D8A",ProcessorArchitecture="MSIL"'. The signature or catalog could not be verified or is not valid. HRESULT: 0x80131045. assembly interface: IAssemblyCacheItem, function: Commit, component: {84C66D06-D31F-536F-B79F-71F7E5F4BFE3}
I checked my configuration.
I use Visual Studio 2013 and VS 2010 is installed too, and some SDKs.
VS 2013 uses OLD version of SN for signing my projects and this old version is located in the
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\sn.exe"
Just for case I changed the path to sn tool 4.5:
"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\sn.exe"
and my interop files were installed without any issue!
this is a sequence I use for creating key files:
sn.exe -m
sn.exe -k CONTAINER-Authenticode.snk
sn.exe -i CONTAINER-Authenticode.snk CONTAINER
sn.exe -pc CONTAINER CONTAINER-Authenticode.pbk
Added system variables SN_ContainerName=CONTAINER; SN_Option=-Rc
The my question is, why is that, what version of SN should I use, where can I read something about that, and where can I made any error.
Every time i try to compile i'm getting this error:
System.BadImageFormatException: 'An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)'
when i try to run session = PXCMSession.CreateInstance();
I'm running Windows 10 pro, 32 bit operating system.
Added reference to file:
c:\Program Files\Intel\RSSDK\bin\win32\libpxcclr.cs.dll
added to post build evenent:
if "$(Platform)" == "x86" ( copy /y "$(RSSDK_DIR)\bin\win32\libpxccpp2c.dll" "$(TargetDir)" ) else ( copy /y "$(RSSDK_DIR)\bin\x64\libpxccpp2c.dll" "$(TargetDir)" )
And in build tab changed platform target from Any CPU to X86
That exception is usually, in my experience, due to a x64/x86 conflict. Are you definitely referencing the x86 version of libpxcclr.cs.dll?
The fix is to go back to cmake and build with the x64 compilers on your system. If you don't see the prompt for the compiler version, delete the "build" directory and try cmake-gui again. All the C# examples work in x64 but don't in 32-bit.
I'm trying to interop with the ImageMagick library in Mono on a Mac. I installed the ImageMagick library with MacPorts and have verified that the file libMagickWand.dylib exists in the directory /opt/local/lib. I've also created a soft link to that file in the directory /usr/local/lib.
Here's my DllImport statement:
[DllImport("libMagickWand", EntryPoint = "MagickWandGenesis")]
static extern void WandGenesis();
Here's my App.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<dllmap dll="libMagickWand" target="/opt/local/lib/libMagickWand.dylib" />
</configuration>
And, at the call to WandGenesis();, I get a DllNotFoundException, with the message 'libMagickWand'.
I've read this page and I think I'm following all the rules. Is there anything else I can try?
Update:
I ran the .exe with MONO_LOG_LEVEL=debug. Here is the pertinent information:
Mono: DllImport error loading library 'dlopen(/opt/local/lib/libMagickWand.5.dylib, 9):
no suitable image found.
Did find: /opt/local/lib/libMagickWand.5.dylib: mach-o, but wrong architecture'.
wrong architecture: I'm running Snow Leopard in 32-bit mode and always have. I installed ImageMagick with MacPorts, and I installed Mono with the Mac package from mono-project.com. What would have been compiled with a different architecture?
Update:
I think I found my problem:
MacBook-Pro:lib ken$ lipo -info libMagickWand.5.dylib
Non-fat file: libMagickWand.5.dylib is architecture: x86_64
Update:
...but I'm still having issues. I can't seem to figure out how to compile ImageMagick with i386 architecture. When I try to do so using flags, it complains about other libraries that were compiled as 64-bit.
Update:
Mono on Mac OS X is 32 bit (at least usually, you can confirm that with mono --version) and you are trying to link with 64bit binary which is not possible. You have to provide 32-bit binary (or use 64-bit Mono).
Do you have the error even when only the library's file name is in the target and the library is placed appropriately (or the DYLD_LIBRARY_PATH set)? In such case please provide the output of mono executed with MONO_LOG_LEVEL=debug.
I have a complex solution (developed under Windows, deployed under GNU\Linux) with a number of unit-testing projects, using NUnit 2.9.3.
Here's a reference from project:
<Reference Include="nunit.framework, Version=2.9.3.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\Program Files\NUnit 2.9.3\bin\net-4.0\nunit.framework.dll</HintPath>
</Reference>
I downloaded and built NUnit 2.9.3 from source:
$ xbuild solutions/MonoDevelop/NUnit.Framework.sln /p:Configuration=Release
and installed into GAC:
$ gacutil /i solutions/MonoDevelop/bin/Release/nunit.framework.dll
$ gacutil /l nunit.framework
The following assemblies are installed into the GAC:
nunit.framework, Version=2.9.3.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77
Number of items = 1
and deleted local mono nunit installation:
$ rm /usr/lib/mono/2.0/nunit*
$ rm /usr/lib/mono/4.0/nunit*
but when I try to build my solution:
$ xbuild MySolution.sln | grep error
: error CS0006: Metadata file `/usr/lib/mono/2.0/nunit.framework.dll' could not be found
What do I wrong?
Build tools do not normally resolve assemblies from the GAC (except possibly as a last resort). On .NET they they "assembly folders" registered in the registry. On Mono they use "pkgconfig". You may have removed the nunit assemblies but you did not remove or fix the pkgconfig ("pc") file that tells xbuild and MonoDevelop where to find the dll.
This kind of stuff is why it's a bad idea to alter things installed by packages. You should either uninstall the package properly, or use the appropriate environment variables to override packaged stuff.
In this case, I would suggest you create a pc file for your new nunit assemblies, and put it into the /usr/local/lib/pkgconfig directory (/usr/local is the prefix for installing stuff you build from source), or put it somewhere else and have that somewhere else included in the PKG_CONFIG_PATH environment variable.
See also:
The MonoDevelop FAQ entry
And for some general background on configuring Mono environments, see:
Parallel Mono Environments
How not to break Mono installations
What I will try is to copy the NUnit 2.9.3 to my source file folder such as (solution folder)\lib. Then add this reference locally and make sure the tag matches this local path.
When that is configured, I think xbuild should use this local copy directly instead of reading GAC or other preconfigured paths. If not, I will report a bug to Mono team.
The /pkg option of the mono compiler worked fine for me ...
dmcs test.cs /r:System.Configuration.dll /r:System.dll /pkg:nunit
FWIW, I installed nunit using the apt-get package manager (on Ubuntu) ...
sudo apt-get install nunit