Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

DLL compiled with .NET 4.5 doesn't work

Discussion in 'Experimental Scripting Previews' started by julianilevy, Sep 9, 2017.

  1. julianilevy

    julianilevy

    Joined:
    Sep 21, 2016
    Posts:
    10
    Hi!

    I'm trying to use Microsoft.Kinect.Tools.dll, a Kinect Native DLL compiled with .NET 4.5 which I imported into my Unity project to record videos in .xef and .xrf format.

    Despite all my attempts, Unity never detects this DLL as part of the project, and always gets this error:
    Code (CSharp):
    1. Assets/KSRecordTest.cs(4,24): error CS0234: The type or namespace name `Tools' does not exist in the namespace `Microsoft.Kinect'. Are you missing an assembly reference?
    I even tried to add the reference to the .csproj file by hand:
    Code (CSharp):
    1.     <Reference Include="Microsoft.Kinect.Tools.dll.dll">
    2.       <HintPath>Assets\Plugins\Microsoft.Kinect.Tools.dll</HintPath>
    3.     </Reference>
    But I've only been able to make Visual Studio import it properly until Unity rewrites the .csproj files again (I could write "using Microsoft.Kinect.Tools" and use it for a while in my script).

    Does this happens because .NET 4.6 is still on experimental phase, therefore being impossible to use higher .DLLs than .NET 3.5?
    Or maybe it has to do with the DLL being Native. I'm not really sure.

    Any help is appreciated.

    Thanks!
     
  2. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    Yes, it is not possible to use assemblies compiled against any version of .NET higher than 3.5 with the existing Mono runtime in Unity. You will need to try with the experimental runtime.

    This is the expected behavior. The creation of .csproj files is one-way. Unity will write them for Visual Studio to understand, but Unity does not read back changes from Visual Studio.

    If you put a managed DLL in the project though, Unity should include it in the build. So I think the root cause here is that this assembly is built against .NET 4.5.
     
  3. julianilevy

    julianilevy

    Joined:
    Sep 21, 2016
    Posts:
    10
    I was actually trying with the experimental runtime (.NET 4.6). Sorry I didn't clarify it before.
    Yes, it gets included in the build. Anyway, the DLL doesn't work in the build nor the editor.


    I made a clean new project with Kinect Tools DLL only. This is my config:



    This is how a script looks in Visual Studio (Microsoft.Kinect.Tools never appears in the References list):



    And this is how it looks with the DLL added by hand to the .csproj file (Anyway, like you said, Unity ignore this):



    Here is the DLL I'm using:
    https://drive.google.com/file/d/0B2P1mRmx83AwOHZlOGc2THNVOVE/view?usp=sharing


    Is there some special way to get a DLL compiled against .NET higher than 3.5 work with the .NET 4.6 experimental runtime?
    If not, will the .NET 4.6 final runtime fix this issue?

    Thanks for answering!
     
  4. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    Thanks for clarifying. This should work the the .NET 4.6 experimental profile. Or at least, we should be able to get it to compile. I'm not sure this this assembly will work at runtime.

    I think you want to add the Microsoft.Kinect.Tools.dll to a file named mcs.rsp in the Assets/ directory of the project. The contents of the mcs.rsp file should be this:

    -r:Microsoft.Kinect.Tools.dll

    that will tell the C# compiler to reference this assembly during the build. It will also cause the .csproj generation code to add it as a reference.
     
  5. julianilevy

    julianilevy

    Joined:
    Sep 21, 2016
    Posts:
    10
    I did that and now I'm getting this error:
    Code (CSharp):
    1. error CS0006: Metadata file `Microsoft.Kinect.Tools.dll' could not be found
    2.  
    3. Compilation failed: 1 error(s), 0 warnings
    I tried using -r:Microsoft.Kinect.Tools (without .dll extension) and placing the DLL inside Plugins folder, but it doesn't seem to fix the problem. Also, the Microsoft.Kinect.Tools.dll meta file exists, so I don't know why it doesn't work.

    Do you have any solution for this?

    Thanks!
     
  6. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    The terminology here can be a bit confusing. When the C# compiler says "Metadata file <whatever> could not be found" it does not mean the Unity .meta file. You can mentally replace the word "Metadata" with "Assembly" or "DLL" when you read that error message.

    I think this is happening because the C# compiler is looking in the current directory (Assets/) for the Microsoft.Kinect.Tools.dll file. Try either a relative or absolute path, maybe something like

    -r:plugins/Microsoft.Kinect.Tools
     
    dphuong98 likes this.
  7. julianilevy

    julianilevy

    Joined:
    Sep 21, 2016
    Posts:
    10
    It worked with: -r:Assets/Plugins/Microsoft.Kinect.Tools.dll

    Anyway, a new error appeared:
    Code (CSharp):
    1. FileNotFoundException: Could not load file or assembly 'Microsoft.Kinect.Tools, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies.

    This one is strange, because my script still has errors:


    And the Microsoft.Kinect.Tools reference wasn't even imported:


    But Unity doesn't show anything wrong on console:


    This is only until I press the Play button, and then the error I showed above pops up:



    This only happens inside Unity, because I tested the same code in an external VS Project with almost no references and it worked (could record videos and all):




    What could it be?
     
    dphuong98 likes this.
  8. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    I'm not sure now. Maybe try moving the Microsoft.Kinect.Tools to the Assets/ directory and make the mcs.rsp file not have a path to the file. It looks like the C# compiler cannot locate that file properly.
     
  9. julianilevy

    julianilevy

    Joined:
    Sep 21, 2016
    Posts:
    10
    I also tried that but didn't not work.

    Here is the Unity project, in case you want to try it by yourself: https://drive.google.com/open?id=0B2P1mRmx83AweGQ3UlRwcXB6OWs

    if I get it to work I'll reply again explaining how I did it

    Thanks for answering!
     
  10. joncham

    joncham

    Unity Technologies

    Joined:
    Dec 1, 2011
    Posts:
    276
    It looks like your Microsoft.Kinect.Tools.dll assembly is detected as a native dynamic library by the plugin importer. That means it will be treated as a native dynamic library, and not be available as a reference for managed code. Is this a C++ library? C++/CLI?
     
  11. julianilevy

    julianilevy

    Joined:
    Sep 21, 2016
    Posts:
    10
    I decompiled the dll with dotPeek (JetBrains), and looking at some classes I saw this "using <CppImplementationDetails>":

    So I guess Microsoft.Kinect.Tools.dll was written in C++/CLI.

    Is this the only way to use a Native DLL in Unity?:
    Code (CSharp):
    1. [RootSystem.Runtime.InteropServices.DllImport("NativeDLLName"]
    If that's the case it doesn't help me.

    Do you know another possible solution? If not, will be possible in future versions of Unity to use Native DLLs in the same way as Managed DLLs?
     
  12. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    Unity does not support C++/CLI at all, and probably won't in the future. So DLLImport with p/invoke (as you mentioned) is the only way to interact with native code.
     
  13. julianilevy

    julianilevy

    Joined:
    Sep 21, 2016
    Posts:
    10
    Oh, I'll see how I manage then.

    Thanks for all the help Josh!
     
  14. julianilevy

    julianilevy

    Joined:
    Sep 21, 2016
    Posts:
    10
    Well, after some attempts I made it work with [DllImport]. I'll leave the link to the project for anyone interested in using it and learn from it: https://mega.nz/#!pkpU2YDZ!Vo5keYsxxpvav90OE6CQK4K63uryq8h-r4vyWWCbcoI.
    It includes the Unity project (C#) and the C++ project (which builds a DLL whose purpose is to set up connection methods between the Unity project and Microsoft.Kinect.Tools.dll).

    Some things to keep in mind:
    • The Scripting Runtime Version has to be .NET 4.6 (Edit > Project Settings > Player).
    • Both DLLs, Microsoft.Kinect.Tools and KinectUtilities (the one I made), have to be inside the Unity Editor folder (along with the .exe) in order to get loaded. The same with the Build, they have to be placed inside the build folder, next to the .exe.
    • In C#, when using [DllImport] to call a native method, every parameter that use pointers (*) in the C++ code require this attribute [MarshalAs(UnmanagedType.LPStr)] before the type.
    • When programming a Native DLL in C++ (not necessarily this case):
      • In headers, extern "C" __declspec(dllexport) has to be included before every method that will be called with [DllImport] in C#.
      • In the project properties, Common Language Runtime Support needs to be enabled.
      • Also, if another DLL is being used (added to References), it's .NET version has to be equal or lower than the project's one. This can be changed in the project .vcxproj file, adding <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> (or any other version) in the label ProjectConfigurations. The Solution Platform must be the same than the external DLL too (I used x64 for Microsoft.Kinect.Tools).

    I hope this can be helpful to someone in a future!
     
  15. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    I haven't look at the project, but in general, MarshalAs(UnmanagedType.LPStr) should only be used to marshal strings. Other pointer types should be passed across the managed-to-native boundary using System.IntPtr.
     
  16. julianilevy

    julianilevy

    Joined:
    Sep 21, 2016
    Posts:
    10
    Oh, you are right, it should only be used to marshal strings.

    Thanks for the correction!
     
  17. GerodruS

    GerodruS

    Joined:
    Aug 3, 2015
    Posts:
    7
    Hi! Thank you to sharing your project!
    I've tried it but failed ><
    First question: you wrote that dlls have to be inside the Unity Editor folder. What folder exactly did you mean? Assets/Editor? Assets/Plugins/Editor? Another one?
    Second: after some googling I've found out, that, maybe, there is a mistake in code and i need to use
    [DllImport("KinectUtilities", ...
    without ".dll" but not
    [DllImport("KinectUtilities.dll", ...
    But after that I've got a crash of whole unity editor, not only an error to the log.
     
  18. julianilevy

    julianilevy

    Joined:
    Sep 21, 2016
    Posts:
    10
    Sorry for the late response GeorodruS!

    I was referring to this when I said DLLs shall be inside the Unity and the builded game (.exe) folder:



    As for the .dll extension, I just tried executing the code only with [DllImport("KinectUtilities") and it worked just like when the extension was included.

    If you still have problems, this time I will be more alert to the replies!
     
    gheorghelisca likes this.
  19. moulikirs

    moulikirs

    Joined:
    Jun 22, 2019
    Posts:
    5
    hello i was facing a problem related to this all my visual studio projects are in .net framework 4.6 and in my unity scripting runtime version is set to .NET 4.x equivalent and api compatiblity is set to .NET .4.x while i am importing my visual studio project dlls to unity assets i am getting an error stating :
    Assembly 'Assets/Connection.dll' will not be loaded due to errors:
    Unable to resolve reference 'PresentationFramework'. Is the assembly missing or incompatible with the current platform?
    Reference validation can be disabled in the Plugin Inspector.


    i dont know what did i miss
    i did the same procedure in unity 2017.2.5 i worked i set both the frameworks to 4.6 and added my dll files in assets folder but i was unable to build in unity so i upgraded to unity 2019 version now i am struct in this my present unity version in 2019.1.7

    any help would be appreciated
    thank you Screenshot (10).png
     
    Last edited: Jun 22, 2019
  20. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    I believe that PresentationFramework.dll is part of WPF, which is not supported by Unity. I'm surprised this worked in earlier versions of Unity, to be honest.

    Do you need to use WPF? Or is is possible to remove this dependency in your project?