You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP项目中如何将Native DLL置于子文件夹并正常引用?

可行解决方案(除了复制到输出根目录)

我来给你几个在UWP环境下验证过的替代方案,帮你把几十Native DLL整理到子文件夹里,同时避免加载失败的问题:


方案1:在C++ UWP项目中显式加载指定路径的DLL

UWP默认只会在主执行目录搜索依赖,但你可以在C++代码里主动指定子文件夹路径加载DLL,完全掌控加载逻辑:

  1. 先在C#项目里配置Native DLL的部署路径:修改<Content>节点的<Link>属性,把DLL放到子文件夹(比如NativeDlls\),确保复制到输出目录时保持结构:
    <Content Include="..\..\path\to\opencv_features2d411d.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <Link>NativeDlls\opencv_features2d411d.dll</Link>
    </Content>
    
  2. 在C++ UWP项目的初始化代码(比如DLL入口或初始化函数)中,用LoadLibraryEx显式加载这些DLL:
    #include <windows.h>
    #include <winrt/Windows.Storage.h>
    
    bool LoadRequiredNativeDlls()
    {
        // 获取应用安装目录(如果是打包在应用包内的DLL用这个)
        auto installedPath = winrt::Windows::ApplicationModel::Package::Current().InstalledLocation().Path();
        std::wstring dllFolder = installedPath + L"\\NativeDlls\\";
    
        // 逐个加载需要的DLL
        HMODULE hFeaturesDll = LoadLibraryEx((dllFolder + L"opencv_features2d411d.dll").c_str(), 
                                            nullptr, 
                                            LOAD_WITH_ALTERED_SEARCH_PATH);
        if (!hFeaturesDll)
        {
            // 处理加载失败,比如记录错误码
            DWORD err = GetLastError();
            // 这里可以抛出异常或返回错误状态
            return false;
        }
    
        // 加载其他DLL...
        return true;
    }
    
  3. 调用这个初始化函数在C++代码执行任何依赖Native DLL的逻辑之前,确保DLL已加载。

方案2:延迟加载+自定义加载回调(适配隐式链接场景)

如果你的C++项目是隐式链接这些Native DLL(也就是通过.lib文件引用,编译时自动生成依赖),可以用延迟加载特性配合自定义回调来重定向加载路径:

  1. 在C++ UWP项目属性里开启延迟加载:
    • 打开链接器 -> 输入,在延迟加载的DLL中添加所有需要重定向的Native DLL名称(比如opencv_features2d411d.dll)。
  2. 实现延迟加载的回调函数,在系统尝试加载DLL时修改路径:
    #include <delayimp.h>
    
    FARPROC WINAPI CustomDllLoadHook(unsigned int reason, DelayLoadInfo* info)
    {
        if (reason == dliNotePreLoadLibrary)
        {
            // 拼接子文件夹路径
            std::wstring dllPath = L"NativeDlls\\";
            dllPath += info->szDll;
    
            // 从子文件夹加载DLL
            HMODULE hDll = LoadLibraryEx(dllPath.c_str(), nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
            if (hDll)
            {
                return reinterpret_cast<FARPROC>(hDll);
            }
        }
        // 加载失败时 fallback到系统默认逻辑
        return nullptr;
    }
    
    // 注册回调函数
    PfnDliHook __pfnDliNotifyHook2 = CustomDllLoadHook;
    PfnDliHook __pfnDliFailureHook2 = CustomDllLoadHook;
    
  3. 这样系统在延迟加载DLL时会优先调用你的回调,从指定子文件夹加载,无需修改C#项目的部署逻辑(只要DLL在子文件夹里即可)。

方案3:调整C++项目输出结构,保持依赖的相对路径

如果你的C++ UWP项目本身是生成DLL的,可以直接调整它的输出目录,让依赖的Native DLL和C++ DLL放在同一个子文件夹里,利用相对路径自动加载:

  1. 在C++ UWP项目属性中:
    • 进入常规 -> 输出目录,设置为$(SolutionDir)YourCSharpProject\bin\$(Configuration)\$(Platform)\NativeDlls\(根据你的项目结构调整路径,确保输出到C#项目的NativeDlls子文件夹)。
    • 进入链接器 -> 常规,设置附加库目录为Native DLL所在的原始路径,确保编译时能找到.lib文件。
  2. 在C#项目中引用C++ DLL时,设置<Link>属性指向NativeDlls\YourCppDll.dll,这样C++ DLL和所有Native DLL都会在同一个子文件夹里,系统能通过相对路径自动找到依赖。

关键注意事项

  • UWP沙箱限制:确保子文件夹在应用可访问范围内(应用安装目录或本地数据文件夹都是合法路径,不能用绝对路径指向系统目录)。
  • 调试符号文件:把pdb文件也同步部署到对应的子文件夹,修改C#项目的<Content>节点:
    <Content Include="..\..\path\to\opencv_features2d411d.pdb" Condition="'$(Configuration)'=='Debug'">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <Link>NativeDlls\opencv_features2d411d.pdb</Link>
    </Content>
    

内容的提问来源于stack exchange,提问作者Softlion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 21:02:41