Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you use C++ DLLs in C# code in a UWP?

Tags:

c++

c#

dll

uwp

I wrote a C++ Class Library in Visual Studio that just defines a function that invokes some Python:

#pragma once

#include <Python.h>

extern "C"
__declspec(dllexport)
void python()
{
    Py_Initialize();
    PyRun_SimpleString("2 + 2");
}

I made another project in the same solution that was a C# Blank Universal app. I tried to reference the DLL generated from the previous project I mentioned:

using System;
...

namespace StartupApp
{
    ...
    sealed partial class App : Application
    {
        private const string CPPPythonInterfaceDLL = @"pathtodll";

        [DllImport(CPPPythonInterfaceDLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
        private static extern void python();

        public static void Python()
        {
            python();
        }
        ...
        public App()
        {
            ...

            Python();
        }

        ...
    }
}

The app is in a Release configuration.

Whenever I try to run the app on my Local Machine, it always gives an error:

The program '[2272] StartupApp.exe' has exited with code -1073741790 (0xc0000022).
Activation of the Windows Store app 'ab6a8ef2-1fa8-4cc7-b7b3-fb7420af7dc3_7dk3a6v9mg4g6!App' failed with error 'The app didn't start'.

So my question is this: can I reference a C++ class library from a C# UWP project? Or does the security on UWP apps not allow this?

Or is it because of Python.h?

EDIT:

I built the project with a DLL project and a Runtime Component that wrapped it, and now I have this error:

An exception of type 'System

'System.DllNotFoundException' occurred in StartupApp.exe but was not handled in user code

Additional information: Unable to load DLL 'pathtodll': Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

I added a user to the DLL with the object name "Everyone" (I am not sure how else to give everyone permissions) but the error still comes up.

like image 808
M3579 Avatar asked Nov 03 '15 01:11

M3579


1 Answers

Firstly, UWP can't consume a legacy C++ dll just by DLLImport.

If you want to expose legacy c++ functions to C#, the first suggestion is to wrap that C++ logic using a WinRT component. Then you can reference this component in UWP application by following steps: adding it to the project, open the files' properties in the Solution Explorer window, and mark them as content to be included in the app package. This post would be helpful. This one provides more detailed steps.

If you want to PInvoke the dll, you can follow these steps (You can refer to this MSDN post):

  1. Add win32 dll into your UWP project making sure to set its type as 'content'

  2. Then in the proper cs file, using DllImport to PInvoke the dll.

There is one more thing: You need to make sure your Python dll is not using prohibited APIs in WinRT. You can check this by using /ZW compile option for the dll.

like image 116
Fangfang Wu - MSFT Avatar answered Oct 02 '22 22:10

Fangfang Wu - MSFT