-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Instantiation of SharpFont.Library throws System.BadImageFormatException. #100
Comments
The manual installation of SharpFont.Dependencies probably missed the addition of SharpFont.Dependencies.props to your sln file, which includes a version of freetype6.dll (the library that SharpFont wraps) in what gets copied to the output directory. The NuGet packages are targeted to .NET 4.5, but should have no problem running on .NET 3.5+. If you have some reproducible setup I can look into why the installation was not working automatically. You'll also want to include SharpFont.props for cross-platform support (copies in a .dll.config that has mappings for the other supported OSs) There is also the possibility that this is just a mismatch of 32/64 bit binaries. The next release of SharpFont and SharpFont.Dependencies will be able to select the correct 32/64 bit versions of freetype6.dll, that will happen whenever I have time to do a release next |
Mono ships a tool called monodis, the default usage is simply disassembly (i.e. Convert to IL listing), but there is a command line switch |
Oh, of course, the Microsoft equivalent tool is called |
Platform needs to be anycpu (https://msdn.microsoft.com/en-us/library/zekwfyz4.aspx) to auto select . The .net runtime cannot cross-load 64-bit SharpFont with 32-bit freetype dll nor vice versa, so it is best to build SharpFont as anycpu and use whichever bit freetype as is the host os runtime. |
SharpFont only depends on freetype6.dll (or libfreetype.so.6 or whatever other naming scheme is on other OSs). For development, AnyCPU is what you want - for deployment, if you want to ship AnyCPU, you'd need to ship two copies of freetype6.dll (and any other native binaries you might depend on) and select one based on the arch detected at runtime. The examples project does this here: https://github.com/Robmaister/SharpFont/blob/master/Source/Examples/Program.cs I'm more curious about the NuGet failing bit, as it might be indicative of a problem with the newer PCL structure or my NuGet packaging of them |
Hmm, actually x64 platform is capable of executing platform=x86 IL code, but in that case the selection of freetype dll based on host platform would be wrong - when executing x86 IL code on 64-bit platform, the host launches the 32-bit runtime, and won't be able to use 64-bit dll despite the host being 64-bit. So I really think platform should be anycpu and let the host auto select, and install host-matched freetype dll. |
Choosing the right dll at install time is another option. If you're not using an installer though (distributing a zip? Something small that you could reasonably move between hosts on a flash drive?) you'll either have to always run x86 (AnyCPU has a "Prefer 32-bit" flag) or distribute both in the zip and choose at runtime. I suppose you could also force x64 if you wanted to |
@Robmaister I'm not sure what to tell you. What I gave above are the steps to reproduce. If you would like more information you can have it, but I don't know what else to add except that the package (installable from VS2017) seems to be broken. When I work around the breakage I receive errors that I'm not sure how to follow up on due to my unfamiliarity with .NET but it seems like an executable loading issue. I will try to add SharpFont.props by hand and update this issue. |
@R030t1 yup, this exception is a problem with dll loading, though - so reproduction would require all of the "state" around the code - like either the steps you took in manual installation or just the solution as it is (and also if you're running a 32-bit or 64-bit of Windows) Regardless, I'll investigate older .NET projects not properly working on NuGet, I assume this is because I chose lib\net45 and that I'll have to either just do a special nuget thing to make it appear as working on older runtimes, or possibly build multiple versions (compatibility between CLR versions 2.0 and 4.0? side-by-side support?). |
@Robmaister : you are aware that net 3.5, 4, 4.5 are only source-compatible, not binary-compatible, right? I am pretty sure you need at least 3 different SharpFont builds if you are not doing that already. 3.5, 4, 4.5 are simply different runtime. (2.0 is a proper subset of 3.5, but since you have dropped support for runtime 2.0 with SharpFont 4.X, we can ignore 2.0 for the purpose of this discussion) |
@HinTak There is a high degree of compatibility for IL so long as no CLR 4.0 specific features are used as well as in-process side-by-side execution of CLR 2.0 and 4.0. We should be completely clear to build as either 3.5 or 4.5 and not have a problem hosting on either CLR 2.0 or 4.0 I would also like to point out that there is a difference in versioning of the .NET Framework and the CLR. .NET 2.0, 3.0, and 3.5 are all hosted on CLR 2.0 - that is, the CIL remains the same between those versions. 3.0 and 3.5 are C# enhancements only, producing fully compatible IL. CLR 4.0 and .NET 4.0/4.5/4.6 broke compatibility for a handful of reasons, the primary one being support for the |
Only source-level compatibility. Not binary compatible, as I said. The compiled SharpFont dll remembers what versions of assembly dll's it was built with. The system assemblies of different CLR have different versions. |
@Robmaister I didn't do anything out of the ordinary when installing Visual Studio 2017. I am using a 64-bit version of Windows. I'm not trying to be obtuse - I did the average thing in every case when presented with a choice. Also, if what you are saying about CLR/.NET compatibility was true, why are large Windows applications bundled with the .NET runtimes they use? My experience installing e.g. games makes me believe @HinTak is correct. The examples you gave seem to be concerning purely IL code, and not binary code which interfaces with the CLR or .NET code. |
@R030t1 Sorry if I came off as short or rude, that was not my intention. With a 64-bit OS and running your code as a 64-bit process, you will run into a bug that was fixed in Robmaister/SharpFont.Dependencies#4 - it tries to use the 32-bit freetype6.dll instead of the 64-bit one, which throws the error you received. I believe this is the problem you are facing. Looking into this further, the side-by-side is for hosting entire AppDomains as 2.0 or 4.0 side-by-side (likely to support services using shared processes on Windows) and not individual assemblies loaded in the domain. You can also force an assembly targeting CLR 4.0 to load on CLR 2.0, but this requires manually referencing the old CLR, as per the first StackOverflow link. No way to do this on an individual assembly loaded as a dependency. End user applications need the targeted CLR, which is why they are distributed with them, but the libraries they depend on can be any older version that gets loaded into a compatibility profile (only forward compatibility). For example, when we were targeting .NET 2.0, MonoGame was targeting .NET 4.5 and was still able to use SharpFont as a dependency just fine. So I believe the way forward in terms of packaging is one SharpFont package with a 3.5 build (only CLR 2.0 version of .NET that isn't end-of-life on the MS side) and a PCL build for all other platforms looking forward, to address the .NET framework version part of the original issue. |
@Robmaister : it seems that you completely misunderstood the stackoverflow link you referenced. It said:
This is actually exactly how I build and target older framework - you have to compile and link against the older runtime libraries. The outcome is source-compatible but not binary-compatible between different versions of CLR. Anyway, I did download the SharpFont nuget package and unpacked it manually and had a look. There are some hard coded paths... There is one other possibility: the freetype dll you distribute itself may have unsatisfied dependencies. |
@HinTak Ah that makes more sense - the result will still be a .NET 3.5 build and a PCL build (plus .NET 2.0 w/ LINQBridge as mentioned in #104), correct? So in total 3 binaries built and packaged into two separate NuGet packages? Are there any other considerations for platforms that need a non-PCL build? Also which paths are hardcoded right now? Anything that's not a relative path? I'm aware of the hardcoded "x86" in the path to freetype6.dll, which will be fixed with the next release as I mentioned. The only other possibility is not having the correct version of the VC Runtime. It is the only dependency of freetype6.dll, one that I believe can be removed with some modification of the .sln file that is provided by FreeType. |
@R030t1 Were you able to find a solution, or work around the issue at all? I'm having the same problem -- had to install SharpFont.Dependencies before installing SharpFont would work in NuGet. Targeting .NET 4.6.1. Using AnyCPU (and tried others). But instantiation of SharpFont.Library throws System.BadImageFormatException. |
@JibbSmart No, I have found no solution. I ended up migrating to C++ as I could not find a managed language with comprehensive FreeType bindings. |
Nevermind. SharpFont.Dependencies.props copies the wrong DLLs across. Changed that, and it's all good. |
@JibbSmart If you have suitable knowledge of C#, please see how your solution relates to #111 and #113. |
The only solution for me was to copy the correct DLL from the nuget package folder (in my case the x86 one) and added it manually to the project (not as reference but as a normal item). Then I changed the build action to "Content" and copy to output directory to "Always". Moreover I switched my project configuration from AnyCPU to x86. This way it also worked with SharpDevelop. I guess this is what the file SharpFont.Dependencies.props should do. But the path is incorrect and it doesn't work at all. In my case nothing was added to the solution or project file. So I had to do it on my own. Hope this helps. |
What I am doing:
Addition of SharpFont to my project using NuGet was finicky. At first I had to use much older versions of the .NET Framework, then I selected a version which installed properly, and finally I manually installed SharpFont.Dependencies and was able to install SharpFont despite the former saying no package was available for my selection version of the .NET Framework (this happened for all versions >4.0, it didn't matter which I selected).
The text was updated successfully, but these errors were encountered: