Search Unity

Using WinRT APIs from a DESKTOP windows app

Discussion in 'Windows' started by siddartha_, Jun 8, 2015.

  1. siddartha_

    siddartha_

    Joined:
    Apr 17, 2013
    Posts:
    11
    Hi.

    Is this possible? I've searched all around and I found several tutorials on how to do this for "normal" Visual Studio desktop apps, but this seems to require an assembly targeted to the 4.5 version of the .NET framework. I've tried this route, but obviously Unity does not recognize this type of assembly (throws an exception when trying to load it).

    I'm really stuck right now. Any hint would be absolutely awesome.
     
  2. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,676
    It's possible by making a native plugin. All of the WinRT APIs are accessible from C++.
     
  3. siddartha_

    siddartha_

    Joined:
    Apr 17, 2013
    Posts:
    11
    Thanks for the answer.
    Could you provide more details on this approach?
    In order to access WinRT from C++, wouldn't I need to build a managed assembly? Wouldn't this cause the same problems as with a managed C# assembly?

    Thanks in advance!
     
  4. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    What exactly are you trying to achieve? Why do you need to access a specific WinRT API from desktop app?

    When you use C++, you build native library, except that on WinRT you can make a WinRT component (.winmd file), which can be accessed by C# code.
     
  5. siddartha_

    siddartha_

    Joined:
    Apr 17, 2013
    Posts:
    11
    Well, I want to access the Bluetooth LE APIs available on Windows 8 onwards.
    I've already tried the Win32 API route, which was plain hell, and I couldn't make it work, so I wanna give a shot at the WinRT APIs, since it seems to be my only option now..

    So, do I _need_ to make a WinRT component in order to call from C#, or can I expose my functionality via normal C-style function calls?
     
  6. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,676
    Actually, for Windows Desktop in Unity you will not be able to expose it using WinRT Component route, because Mono used in Unity doesn't understand WinRT Components. That means, you'll have to expose the functionality via plain C-style functions and invoke them through P/Invoke.

    What exactly would you like to see in such sample?
     
  7. siddartha_

    siddartha_

    Joined:
    Apr 17, 2013
    Posts:
    11
    Yes, I supposed that would be the case..

    I've tried creating a new "Windows Runtime Component" project in visual studio using one the API calls I want to make.
    Now when I put the generated DLL in Assets/Plugins it seems Unity deals with it fine, but when it comes to calling the C-style function I've put in there, I get "Failed to load [path to my DLL]".

    Could the type of project I chose be a problem? I did so following an MSDN walkthrough..

    Thanks a lot.
     
  8. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,676
    Probably an error in DllImport definition. If you put Plugin.dll to <ProjectDir>\Assets\Plugins\Plugin.dll, your DLLImport attribute should look like this:

    Code (csharp):
    1. [DllImport("Plugin")]
    If it's not that, could you paste the full error from the editor log?
     
  9. siddartha_

    siddartha_

    Joined:
    Apr 17, 2013
    Posts:
    11
    Yep, my DllImport seems right.
    This is the full msg:

    Failed to load 'Assets/Plugins/HardwareService2.dll' with error 'This operation is only valid in the context of an app container.'***, GetDllDirectory returned ''. If GetDllDirectory returned non empty path, check that you're using SetDirectoryDll correctly.
    BTLEManager:Init() (at Assets/Code/Hardware/BTLE/BTLEManager.cs:265)
    [rest of the stacktrace]

    *** this part I've translated from spanish
     
  10. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
  11. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,676
    I see. This error means that the DLL has some flags which prevent it to load in a non-Windows Store environment. This probably happens because you build a windows runtime component, which is meant to run on Windows Store apps, not desktop. Did you try creating a regular win32 DLL instead?
     
  12. siddartha_

    siddartha_

    Joined:
    Apr 17, 2013
    Posts:
    11
    Yes, you're exactly right.
    I managed to make it work!
    I followed the steps here https://software.intel.com/en-us/articles/using-winrt-apis-from-desktop-applications to build a normal Windows DLL project that uses the C++/CX extensions. Unity can call it just fine, and I can even call my C# code back using [UnmanagedFunctionPointer(CallingConvention.Cdecl)]!

    Now, all wchar_t strings arrive to C# all scrambled, but this looks promising indeed!

    Thanks a lot for your help.
     
  13. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,676
    Add [MarshalAs(UnmanagedType.LPWStr)] to string parameters, as by default the marshaller marshals strings as char*.

    I'm glad you were able to make it work :).
     
  14. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,676
    One more thing: make sure to test your app on Windows 7 and/or earlier, and add a fallback route for your code or plainly display a message box that OS is supported. You wouldn't want it to plainly crash I suppose :).
     
  15. siddartha_

    siddartha_

    Joined:
    Apr 17, 2013
    Posts:
    11
    Yep I found that googling around..
    I'll do as you suggest.

    Thanks again!
     
  16. Foriero

    Foriero

    Joined:
    Jan 24, 2012
    Posts:
    584
    Hello, I need to write MIDI plugin that uses WIN 10 SDK. Would you be so kind and provide me your code? So that I can learn from it?