繁体   English   中英

如果删除了未使用的ref类,则DLL无法加载

[英]DLL fails to load if unused ref class is removed

我在尝试在UWP应用程序中编译和使用Windows运行时组件时遇到一个非常奇怪的问题(VS2017社区15.9.13,带NetCore.UniversalWindowsPlatform 6.2.8,不带/ clr但带/ ZW编译)。

基本上是类似Grayscaletransform的东西。 运行时组件实际上按预期方式工作,现在我想删除一些未使用的代码。 但是,一旦我从特定文件中删除它并重新编译,它确实可以编译,链接,但是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

没有人知道如果文件中没有ref类的显式实例化时,是否存在与Windows运行时有关的已知错误,无法正确初始化/使用?

编辑1:

这是完整源代码的链接

您的组件的.winmd文件可能错误。 用C ++制作的WinRT组件产生两个输出,dll和winmd。 两者必须匹配。 您可能有来自不同版本的它们。

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

顺便说一句,对于用经典C ++编写并公开C API的本机DLL,部署更为简单,您在程序包中包含一个DLL,它们就可以使用,如果您要从C#中使用它们,请使用[DllImport]

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

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

可能是Microsoft运行时某处的错误。

这里发生的是您正在混合一些模式。 由于您已经使用/ CX标志编译了C ++代码,因此已告诉编译器启用winrt扩展来生成WinRT DLL。 但是在实践中,您的代码实际上都没有使用CX扩展来实现类。 您正在使用WRL和标准C ++。 编译器查看DLL,没有找到CX风格的WinRT类,因此也没有设置模块。

这基本上是未经测试和不受支持的情况,因为您已经选择说要通过选择UWP组件库项目类型公开参考类,但实际上并没有提供任何参考类。 碰巧,/ CX实际上使用WRL,因此您可以轻推它并初始化状态以使其正常工作,但是您确实在破解系统的实现细节。

我建议使用两个选项,两个都可以使用:只需使项目成为非CX Win32 DLL,然后如上所述初始化模块即可。 或者更好的是,切换到C ++ / WinRT ,这将为您提供比/ CX更好的WinRT类型支持,并使您可以更轻松地在实现中混入经典COM类型。 您可以通过在编译器开关中关闭/ CX标志来开始使用,然后开始相应地更新代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM