簡體   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