天天看点

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!