如果删除未使用的REF类,DLL将无法加载

DLL fails to load if unused ref class is removed

本文关键字:DLL 加载 删除 未使用 REF 如果      更新时间:2023-10-16

我遇到了一个非常奇怪的问题,试图编译和使用UWP应用程序中的Windows Runtime组件(VS2017社区15.9.13带NetCore.universalwindowsalwindowsplatform 6.2.8,无/clr但是/zw(。

基本上是类似于灰度的东西。运行时组件实际上是按预期工作的,现在我想删除一些未使用的代码。但是,一旦我从特定文件中删除它并重新编译,它确实会编译,链接,但DLL不再加载。

这是我必须放入的一些示例代码:

ref class DummyU sealed
{
public:
    DummyU() {}
};
DummyU^ CreateDummyU()
{
    return ref new DummyU();
}

代码使其正常工作,尽管它是a(根本没有引用,而b(没有做任何有用的事情。

删除它的结果:

Exception thrown at 0x0EFF322F (vccorlib140d_app.dll) in TestAppUWP.exe: 0xC0000005: Access violation reading location 0x00000000.

STDAPI DllGetActivationFactory(_In_ HSTRING activatibleClassId, _Deref_out_ IActivationFactory** ppFactory)
{
    return Platform::Details::GetActivationFactory(Microsoft::WRL::Details::ModuleBase::module_, activatibleClassId, ppFactory);
}

dllexports.cpp中的功能是VS的一部分。module_变为NULL

是否有人知道,如果文件中没有明确的实例化,则是否有有关Windows运行时的已知错误?

编辑1:

这是指向完整源代码的链接:

这里发生的事情是您要混合一些模式。由于您已将C 代码与/CX标志编译,因此您告诉编译器可以启用Winrt扩展名来生成WinRT DLL。实际上,您的代码实际上都没有使用CX扩展名来实现类。您正在使用WRL和标准C 。编译器查看DLL,发现没有CX风格的WinRT类,也没有相应地设置模块。

这基本上是未经测试的&不受支持的情况,因为您选择说您想通过选择UWP组件库项目类型来揭示Ref类,但实际上没有提供任何REF类。碰巧的是,在引擎盖下/cx有效地使用了WRL,因此您可以将其推向并初始化状态以正常工作,但是您有点黑客入侵系统的实现细节。

我建议有两种选择,要么可以:只需将项目作为非CX Win32 DLL,并如上所述使模块INIT。或者,更好的是,翻转到C /WinRT,这将使您比/CX更好地支持WinRT类型,并让您更轻松地在实现中更轻松地混合经典的COM类型。您可以通过关闭编译器开关中的/cx标志来开始,然后开始相应地更新代码。

ben

您的组件可能有错误的.winmd文件。C 制造的WinRT组件产生了两个输出,即DLL和WinMD。两者都必须匹配。您可能会从不同的版本中获得它们。

另一个可能的原因是清单中的错误。该应用的清单必须包括所有引用的运行时组件。

顺便说一句,对于用经典C 编写的本机DLL和Exping C API,部署更简单,如果您是从C#消费的,则在包装中包含DLL,并且它们只是使用[DllImport]

更新:您可以用以下代码替换该ref class,在我的PC上工作。

struct ModuleStaticInitialize
{
    ModuleStaticInitialize()
    {
        Microsoft::WRL::Module<Microsoft::WRL::InProc>::GetModule();
    }
};
static ModuleStaticInitialize s_moduleInit;

可能是微软运行时的错误。