簡體   English   中英

使用/ clr:pure項目中的混合DLL

[英]Using mixed DLLs from /clr:pure projects

我正在與一個Dll建立一個項目。

Dll必須支持本機代碼,因此我將其聲明為/ clr。 我的項目最初也是一個/ clr項目,一切都很好。 但是,我想進行一些NUnit測試,因此必須將主項目從/ clr切換到/ clr:pure。

一切仍然可以編譯,但是任何Dll調用都會生成運行時錯誤。 當我恢復為/ clr時,一切正常

在我的Dll中,導出的函數聲明如下:

#define DllExport   __declspec( dllexport )
DllExport bool DisplayScan(bool bShow, bool bAllPasses) { }

我還制作了一個.def文件,其中包含所有導出函數的真實名稱。

LIBRARY "Controller"
EXPORTS
DisplayScan

從我的主要項目中,我的進口貨物申報如下:

#define _DllImport [DllImport("Controller.dll", CallingConvention = CallingConvention::Cdecl)] static
_DllImport bool DisplayScan(bool bShow, bool bAllPasses)

有人遇到過這樣的問題嗎?

好的,現在一切正常

實際上,它從一開始就一直在工作。

道德:不要嘗試將char *轉換為std :: string

奇怪的事情:在/ clr中可以正常使用,直到您從函數返回為止。 它立即在/ clr:pure中崩潰

基本上,您正在執行不支持的操作; / clr:pure和本機DLL導出。 正如該MSDN文章中引述的那樣,“純程序集無法導出可從本機函數調用的函數,因為純程序集中的入口點使用__clrcall調用約定。”

我不確定最佳解決方法。 但是,通過一些試驗,您可能可以利用帶有/ clr選項的__clrcall調用約定。 這是一個有用的鏈接 據我所知,您應該能夠導出這些托管類並從諸如托管NUnit測試項目之類的托管程序集中使用它們,但使用不同的方法簽名將非托管導出保留在那里。 請記住,一旦通過導出公開了任何.net類,它將需要使用__clrcall調用約定。

/ clr:pure的優點

更好的性能:因為純程序集僅包含MSIL,所以沒有本機函數,因此不需要托管/非托管轉換。 (通過P / Invoke進行的函數調用是該規則的例外。)

AppDomain意識:受管函數和CLR數據類型存在於應用程序域中,這影響了它們的可見性和可訪問性。 純程序集可識別域(每種類型均隱含__declspec(appdomain)),因此從其他.NET組件訪問其類型和功能更加容易和安全。 結果,與混合程序集相比,純程序集與其他.NET組件更容易互操作。

非磁盤加載:純程序集可以在內存中加載,甚至可以流式傳輸。 這對於將.NET程序集用作存儲過程至關重要。 這與混合程序集不同,混合程序集由於依賴Windows加載機制而必須存在於磁盤上才能執行。

反射:不可能對混合的可執行文件進行反射,而純程序集則提供完整的反射支持。 有關更多信息,請參見反射(C ++ / CLI)。

主機可控制性:因為純程序集僅包含MSIL,所以在承載CLR並修改其默認行為的應用程序中使用純程序集時,它們的行為比混合程序集更具預測性和靈活性。

/ clr:pure的局限性

本節介紹/ clr:pure當前不支持的功能。

純程序集不能由非托管函數調用。 因此,純程序集無法實現COM接口或公開本機回調。 純程序集無法通過__declspec(dllexport)或.DEF文件導出函數。 同樣,使用__clrcall約定聲明的函數不能通過__declspec(dllimport)導入。 可以從純程序集調用本機模塊中的功能,但是純程序集不能公開本機可調用的功能,因此,必須通過混合程序集中的托管功能來完成純程序集中的功能公開。 有關更多信息,請參見如何:遷移到/ clr:pure(C ++ / CLI)。

Visual C ++中的純模式編譯不支持ATL和MFC庫。

純.netmodules不能作為Visual C ++鏈接器的輸入。 但是,鏈接器接受純.obj文件,並且.obj文件包含netmodules中包含的信息超集。 有關更多信息,請參見.netmodule文件作為鏈接器輸入。

不支持編譯器COM支持(#import),因為這會將非托管指令引入純程序集。

對齊和異常處理的浮點選項對於純程序集不可調整。 結果,不能使用__declspec(align)。 這將導致某些頭文件,例如fpieee.h,與/ clr:pure不兼容。

使用/ clr:pure進行編譯時,PSDK中的GetLastError函數可以給出未定義的行為。

您的問題是調用ConventionCallingConvention = CallingConvention :: Cdecl ...像這樣定義您的函數或使用stdcall或clrcall,clecl用於純C

或問題在這里:定義函數extern不是靜態的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM