C++ 如果删除了未使用的ref类,则无法加载DLL
在UWP应用程序中编译和使用windows运行时组件时,我遇到了一个非常奇怪的问题(VS2017 community 15.9.13和NetCore.UniversalWindowsPlatform 6.2.8,编译时不使用/clr,但使用/ZW) 它基本上是类似于。运行时组件实际上按预期工作,现在我想删除一些未使用的代码。但是,一旦我将其从特定文件中删除并重新编译,它确实会编译、链接,但DLL不再加载 下面是一些我必须输入的示例代码:C++ 如果删除了未使用的ref类,则无法加载DLL,c++,visual-studio,visual-c++,uwp,windows-runtime,C++,Visual Studio,Visual C++,Uwp,Windows Runtime,在UWP应用程序中编译和使用windows运行时组件时,我遇到了一个非常奇怪的问题(VS2017 community 15.9.13和NetCore.UniversalWindowsPlatform 6.2.8,编译时不使用/clr,但使用/ZW) 它基本上是类似于。运行时组件实际上按预期工作,现在我想删除一些未使用的代码。但是,一旦我将其从特定文件中删除并重新编译,它确实会编译、链接,但DLL不再加载 下面是一些我必须输入的示例代码: ref class DummyU sealed { pub
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.
在
dllexports.cpp
中的函数,它是VS的一部分。模块变为NULL
如果文件中没有ref类的显式实例化,有没有人知道windows运行时是否存在任何未正确初始化/使用的已知错误
编辑1:
以下是完整源代码的示例:您的组件可能有错误的.winmd文件。用C++制作的WRET组件产生两个输出,即DLL和WiMD。两者必须匹配。您可能从不同的版本获得它们 另一个可能的原因是清单中的错误。应用程序的清单包含所有引用的运行时组件
BTW,对于用经典C++编写的C++语言和本地C语言API,部署更简单,在包中包含一个DLL,它们只工作,用<代码> [DLLimPurt] < /C> >如果你从C中消耗了。 更新:您可以用以下代码替换
ref class
,在我的电脑上运行
struct ModuleStaticInitialize
{
ModuleStaticInitialize()
{
Microsoft::WRL::Module<Microsoft::WRL::InProc>::GetModule();
}
};
static ModuleStaticInitialize s_moduleInit;
结构模块初始化
{
模块化初始化()
{
Microsoft::WRL::Module::GetModule();
}
};
静态模块初始化s_模块单元;
可能是Microsoft运行时的某个地方出现了一个bug。这里发生的事情是您在混合一些模式。由于您已经用C/CX标志编译了C++代码,所以您已经告诉编译器启用WrRT扩展来生成WRRT-DLL。但实际上,没有一个代码实际使用CX扩展来实现类。您使用的是WRL和标准C++。编译器查看DLL,没有找到CX样式的WinRT类,也没有相应地设置模块 这基本上是一个未经测试且不受支持的情况,因为您选择说希望通过选择UWP组件库项目类型来公开ref类,但实际上并没有提供任何ref类。碰巧在幕后,/CX有效地使用了WRL,因此您可以轻推它并初始化状态以正确工作,但您有点破坏了系统的实现细节 我建议有两种选择,两种都可以:只需将项目设置为非CX Win32 DLL,并如上所述初始化模块。或者,更好的方法是切换到,这将比/CX更好地支持WinRT类型,并允许您在实现中更轻松地混合使用经典COM类型。您可以先关闭编译器开关中的/CX标志,然后开始相应地更新代码
<>本代码不是C++。实际上是Visual C++和.net和.NET的混合……这些都是有效的点,但它最不同。这里是完整来源的链接。只需克隆、恢复nuget包并编译即可。它应该可以工作,但一旦您删除VizarioMediaStream.cpp中的113ff行,它就会中断…您完全正确-这是可行的,所以显式初始化似乎可以工作。。。似乎真的是个虫子。。。谢谢!好的,我明白你关于切换到C++/WinRT的观点,但我认为关于公开的观点实际上并不完全正确,这让我感到困惑。首先,这主要是微软的示例代码,所以我希望他们至少知道自己在做什么。这不是我自己发明的——无论如何,媒体基金会是一场噩梦。其次,我在代码库中确实有相当多的ref类,这些类对于让模块使用C#/.NET非常必要。只是这个单流文件可能没有ref类,但至少对我来说不应该破坏它。我应该澄清一下。我浏览了你共享的项目。具体地说,在您在对另一个答案()的注释中共享的项目中,我所看到的VizarioSource DLL项目中没有ref类。该项目中的所有对象都是经典COM对象。一个没有ref类的编译单元不应该是问题,只要链接模块至少有一个ref类。如果您仍然看到这个问题,并且可以共享源代码,我很乐意再次查看,看看是否可以进一步提供帮助。@BenKuhn可能是这个版本:
struct ModuleStaticInitialize
{
ModuleStaticInitialize()
{
Microsoft::WRL::Module<Microsoft::WRL::InProc>::GetModule();
}
};
static ModuleStaticInitialize s_moduleInit;