您能否在UWP中使用C++ DLLs在C#代码中?

7
我在Visual Studio中编写了一个C++类库,它仅定义了一个调用Python的函数:
#pragma once

#include <Python.h>

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

我在同一解决方案中创建了另一个项目,这是一个C#空白通用应用程序。我尝试引用之前提到的项目生成的DLL:

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 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'.

我的问题是:我能否在C# UWP项目中引用C++类库?或者UWP应用程序的安全性不允许这样做?
还是因为Python.h的原因?
编辑:
我使用DLL项目和包装它的运行时组件构建了项目,现在我有这个错误:
类型' 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))

我将用户添加到了名为“Everyone”的DLL对象中(我不确定如何以其他方式授予权限),但仍然出现错误。

模块是本地的,目前已禁用本地调试。您尝试启用本地调试了吗? - Chef_Code
1个回答

14

首先,UWP不能通过DLLImport直接使用传统的C++ dll。

如果您想将传统的C ++函数公开给C#,第一个建议是使用WinRT组件包装该C ++逻辑。然后,您可以按照以下步骤引用此组件:将其添加到项目中,在“解决方案资源管理器”窗口中打开文件属性,并将它们标记为要包含在应用程序包中的内容。 此文章可能会有所帮助。 这篇文章提供了更详细的步骤。

如果您想PInvoke dll,则可以按照以下步骤进行操作(可以参考MSDN帖子):

  1. 将win32 dll添加到UWP项目中,并确保将其类型设置为“内容”

  2. 然后,在适当的cs文件中,使用DllImport来PInvoke dll。

还有一件事:您需要确保Python dll未使用WinRT中的禁止API。您可以通过使用/d或/ZW编译选项来检查这一点。


我使用了第二篇文章。我需要DllImport哪个DLL,是在DLL Universal项目中的还是在Runtime Component中的?对于/ZW:,是DLL还是Runtime Component项目(请原谅我的问题,我不太熟悉.NET)。 - M3579
我已经更新了这篇文章,加入了PInvoke的用法。你最好也读一下第一篇文章,它解释了将传统的C++ dll移植到UWP的不同方法。 - Fangfang Wu - MSFT
请尝试以下步骤以确保正确添加DLL:将DLL添加到项目中,在“解决方案资源管理器”窗口中打开DLL的属性,并将其标记为要包含在应用程序包中的内容。 - Fangfang Wu - MSFT
我将一个“现有项目”添加到了工程中(该项——Win32类库DLL位于不同的目录中)。然后,在属性中,我选择了“高级”->“生成操作”中的“内容”。对于“复制到输出目录”,我选择了“不复制”。在我的C#代码中,我使用DLL的完整路径。C#代码DllImport该DLL并调用它(在其前面没有指定任何命名空间)。 - M3579
访问被拒绝表明您的DLL未包含在应用程序包中。确保将二进制文件包含在项目中并标记为内容,然后在构建后再次检查它是否出现在Appx中。应用程序无法从其他位置读取或加载任意DLL。您还需要确保调用的API允许UWP和Windows Runtime应用程序。这可以通过使用/ZW编译DLL来检查。此链接有助于查找兼容的API:https://msdn.microsoft.com/en-us/library/windows/apps/br205757.aspx - Fangfang Wu - MSFT
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接