In an attempt to oversimplify my issue, I'll try to keep it short:
I'm using the pro version of Unity, and I have 2 DLLs:
A .NET 3.5 assembly (acting as a COM client)
A .NET 4.0 assembly (with an interface exposed via COM)
The 3.5 uses COM to work with the 4.0. Using the 3.5 assembly in a Windows app works fine, it loads the 4.0 dll using SxS via Type.GetTypeFromCLSID() or Type.GetTypeFromProgID() (which I've confirmed with SxStrace), and can use it's functionality just fine. (The windows app mentions it's dependency on the 4.0 DLL via a manifest, I'm not registering the COM DLL.)
I'm trying to use the .NET 4.0 DLL in Unity. Obviously I can't use it directly, since the current flavor of Mono that Unity uses only supports up to 3.5, thus I created the 3.5 assembly to be my middleman. I'm able to use the 3.5 assembly fine in unity, but either of the Type methods I mentioned before throw NotImplementedException(s), as apparently they aren't supported by Unity (or rather, Mono), so I'm at a loss.
Any ideas?
Although this question was made 1 year ago..sadly the middleman tactic still wont work, it is not possible to use .NET 4.0 dlls within Unity3D since Mono is just not supporting the dependencies.
You could try to remove any 4.0 dependencies from the dll and compile it as 3.5, if that is possible for you.
Related
According to MSDN documentation,
public static Assembly LoadFrom(string assemblyFile)
throws BadImageFormatException if
assemblyFile is not a valid assembly.
-or-
Version 2.0 or later of the common language runtime is currently loaded
and assemblyFile was compiled with a later version.
Actually, there is one extra case - loading assembly that is built for x86 from assembly that runs in x64 mode. Maybe it is included in "not a valid assembly" statement, I don't know. But this is reasonable cause of exception.
Ok, but in .NET 4.5 it doesn't! I have a .NET 4.5 WPF app, that loads different appliations for some reason. It is building for Any CPU and I'm starting it on x64 Win 7. I've been testing it on one executable, that is built for .NET 4.0 x86, and it worked fine. But when I switched my app to .NET 4.0 it began to crash on Assembly.Load method!
So, my question is, am I missing something? If not, then how did they do that - loading x86 assembly from x64 process in .NET 4.5? I'm lacking some understanding at this point.
Update
Thanks to Hans Passant, I've figured out my mistake. Actually the behavior of Assembly.Load is no different. It turned out, I didn't notice Prefer 32-bit option in project settings (or Prefer32Bit tag in .csproj file). That's why my process in .NET 4.5 ran in a 32-bit mode. This setting was true when I created WPF .NET 4.5 project. Then, when I swithced to .NET 4.0 it became inactive because there was no such an option in .NET 4.0. And when I switched back to .NET 4.5 it became false, which is so, I guess, for compatibility purpose.
Let's clear one assumption off the table quickly, there is no possible way to have different behavior on a machine that has .NET 4.5 installed. Targeting 4.0 makes no difference at runtime. The only thing that does is select a different set of reference assemblies, they prevent you from accidentally using a class that's available on .NET 4.5 but not on .NET 4.0.
There is no way to have both 4.0 and 4.5 installed on the same machine. .NET 4.5 is not a side-by-side version of the .NET framework, like 3.5 and 4.0 are side-by-side. Installing 4.5 replaces an installed 4.0 version. The CLR, the jitter, all the runtime assemblies plus the C# compiler.
It is best here to focus on the Platform target setting of your EXE project, that's the one that selects the bitness of the process. The kind of mistakes you can make is forgetting that the setting can be different for the Debug vs the Release build. And assuming that the "Active solution platform" combobox in Build + Configuration Manager has any effect. It doesn't, only the Project + Properties, Build tab, Platform target setting matters. This is a very awkward trap that many programmers have fallen into.
I have external .net library compiled with .net framework 4 (it's provider moved recently to .net 4)
My code currently runs on .net framework 3.5
How to use that external library in my application ?
Moving whole application to .net 4 needs time and testing, so maybe in a future i will do that, but now, what are the possibilities ?
There are no possibilities, the CLR version that comes with .NET 3.5 cannot load 4.0 assemblies. The metadata format was changed. You have to force your app to use the .NET 4.0 CLR version. Do so by recompiling it with VS2010, targeting 4.0, or by using a .config file that contains the <requestedRuntime> element to ask for "v4.0".
Compatibility for .NET 4.0 is excellent btw.
While you cannot load the .Net DLL directly, you can wrap it in a COM interface, and load that COM interface in your .Net 3.5 process.
See Using a .NET 4 Based DLL From a .NET 2 Based Application
For more background information, Microsoft originally added In-Process Side-by-Side in .Net 4 to better support the scenario where an application loads add-ins via COM, and the add-ins were written with various versions of .Net. The ability to load .Net 4 DLLs in a .Net 3.5 process is just a nice side effect of that.
I have developed a Windows application in the 4.0 framework. After deploying my application I have tried to install it in a Windows XP SP2 system, but when I try it I get some kind of requirement error. So I decided to change my application from 4.0 to the 2.0 framework so that it can be installed in any windows OS. Before that I tried with 3.5 and 3.0 but the framework's setup size exceeded 200mb, so I chose 2.0 because it already comes along with windows xp or later. The problem I am having is while changing my framework from 4.0 to 2.0 i'm getting reference problems with system.core and system.linq so now I cant build my project. What needs to be done to fix these reference errors?
The problem is that System.Linq, for example, didn't exist in .NET 2. If you are using anything that required System.Linq methods (such as LINQ or any extension methods), you'll have to rewrite that portion of your code to use .NET 2 only options.
Personally, I would just target .NET 3.5sp1 or .NET 4, and include the web installer, as this is a small addition to your deployment (the 4.0 web installer is under 1mb - many installers include a way to just package this instead of the full framework). Most systems already have .NET 3.5sp1 (and many have 4.0), so the effort to include this in your deployment is typically far smaller than trying to rework your application to avoid it.
I have a .net 3.5 dll and a .net 4.0 dll. The .net 3.5 dll need to call some functions in the .net 4.0 dll. To do this, I made the 4.0 .net dll as a COM server. However, I cannot tlbimp the tlb file exported from the 4.0 dll. Is it possible for a .net dll to call functions from a .net COM server? Thanks.
If possible you should either upgrade the 3.5 to 4.0 or downgrade the 4.0 to 3.5/2.0, so you can properly add the managed reference.
If you can't do that the alternative is to copy the declaration and replace [ComVisible(true)] by [ComImport] - however this may fail with a typecast exception on runtimes earlier than 4.0. I don't know if it works when 3.5 talks to 4.0, you'd have to test.
I have an app that I've upgraded from 3.5 to 4.0. But not all my 3rd party assemblies are built on .net 4.0. How is it that I'm still able to reference those assemblies without any problems? For instance, if another assembly references system.dll 2.0, and my upgraded project references system.dll 4.0 how does .net handle this?
Obviosly this wasn't a problem upgrading between 2.0 and 3.5 because they use the same BCL and CLR versions, but 4.0 uses a completely different BCL and CLR right?
Here's an example. I have an app built using WF (Windows Workflow) in v3.5. I've upgraded the app to v4.0, but I wasn't required to implement all the breaking changes in the new version of workflow. It still using the old 3.5 version of WF.
.NET 4.0 can reference .NET 2.0 assemblies, but the reverse is not true.
.NET 4.0 assemblies support everything that 2.0 had, but adds in things like optional parameters, dynamic types, and etc...
So, since 2.0 doesn't have anything that 4.0 doesn't, 4.0 can easily support 2.0.
BCL and CLR are different but not completely different. Basically they worked hard to not break backwards compatibility.
You could also force your 3rd party assemblies to run under 3.5, as described in this post.