天天看點

C++/CLI“未能加載工具箱項xx。将從工具箱中将其移除”的解決方案

C++/CLI是目前唯一支援C++與.net混合程式設計的語言,但就我個人的使用感受來說,效果不是很理想,這就又出現問題了:

建立一個Window Form Application,将其項目屬性設定為“公共語言運作時支援(/clr)”,建立一個.net的UserControl,命名為uc1,在Form1的設計界面下,從工具箱拖uc1到Form1上,報錯“未能加載工具箱項uc1。将從工具箱中将其移除”,随後,IDE自動将uc1從工具箱中移除。

來自C.Hannosset的解決方案:

Usage and possibilities of the Common Language Runtime Support (/clr Versus /clr:pure - /clr:safe)

or

how to mix .Net custom control with standard C++ code.

================================================================

Here below is a small resume of a response of the feedback issue I encountered, thanks again Tarek.

From: Tarek Madkour

"I looked at your issue and the problem is that you're not compiling your assembly using /clr:pure or /clr:safe.

Controls can only be loaded from a /clr:pure or a /clr:safe assembly.

They cannot be loaded from plain mixed-mode /clr assemblies.

What's happening is that the designer tries to load your assembly and reflect on it to get the control.

When this fails (due to the use of /clr), it just tells you that this control cannot be loaded and removes it from toolbox.

The limitation is on reflection on mixed-mode EXE's not any mixed-mode assembly. Reflection on mixed-mode DLL's works without problems.

A third workaround you can add to the list below is to create a new DLL project that houses your controls and compile it /clr (no need for

/clr:pure there) then reference it from your project.

Two solutions I can think of are:

1. compile your assembly /clr:pure if possible

2. if not, create a new project that houses your controls and compile this one /clr:pure then

reference it from your /clr project"

After some thought, the workaround I propose is the following:

1\ Create an application (exe) that will functionally set up the Main windows and forms. This can be compiled with the /safe or /strict flag

2\ In the same project, Create a .Net dll (Add -> new project -> Window Forms Control Library). In there add as many user control as you want to.

=> Consequences:

Once the dll is compiled, the user control are available to the exe form window of the executable (application) - remember the application should be safe or pure.

You can then create a dll containing all the user control and another dll containing the mainly C++ core functionality. As the dll supports mixed-mode you can have C++/STL code mixed up with .Net user controls.

This kind of solution is even forcing us to structure our code as we end up with:

- a small application containing the skeleton of the functionality to implement - pure .Net application.

- an interface and/or user control dll with all the specific user interactions.

- a 'core' dll containing the functionalities to implement.

相信各位的英文比我強,這裡隻是總結一下:

方案1:将項目的屬性設定為“純 MSIL 公共語言運作時支援(/clr:pure)”。

方案2:将所有的UserControl拿出來,放到一個單獨建立的“Windows窗體控件庫”項目中,并從目前項目引用那個控件庫。

方案3(自己想到的):放棄在設計界面執行此類操作,改在背景通過代碼添加。

評價(僅代表個人觀點):

方案1實在不算是一個解決辦法,如果使用純CLR,那直接用C#、VB.net不是更友善。

方案3雖然可行,但如果是一個複雜控件或需要設定很多屬性,就需要編寫大量代碼,而且每次想看結果,隻能通過運作程式,因為如果将代碼寫在Form1的InitializeComponent方法裡,那在你移走它們之前,Form1的設計器就再也打不開了。是以此方案隻适合一些簡單控件的處理。

就目前來看,隻有方案2才算是一個真正意義上的解決方案。

Good luck!