2013-06-20 61 views
2

我有一个相当大的项目写在非托管的C + +和生成一个DLL。我希望能够在.Net项目中使用该DLL(在这种情况下,只是一个简单的WinForm应用程序)。我用/ clr set重建了DLL。它成功建成。在我的WinForm项目中,我选择了“添加引用”,选择了“项目”选项卡,然后选择了DLL项目。它已成功添加为我的WinForm项目中的参考。但是,我无法使用该DLL。我想为它添加一个using指令,但我不知道DLL的名称。我尝试使用与该文件相同的名称,但它不起作用。我如何知道在using指令中使用它的名字?在C#项目中,如何引用用C++编写的项目并使用/ clr编译?

非常感谢!

ROBR

+0

我明显地留下了一些东西。通过浏览到DLL文件,我将DLL引用添加到我的WinForms项目中。当我双击参考时,我的ObjectBrowser窗口打开。 DLL对象以接口符号显示,与System相同。但系统可以扩展,当然它下面列出了大量的东西。我的DLL无法扩展,并且似乎没有任何内容。我什么步骤离开了? –

+0

忘记将'ref class'添加到您的源代码中?忘了让他们公开?我们无法从这里看到你的屏幕,你必须用*字*来描述它。从类库项目模板中创建一个“hello world”版本。 –

回答

1

/clr开关可以用来与其他C++代码混合.NET类型(ref classinterface class)。它不会神奇地使C#中的本机C++代码可用。

除了其他原因,C++代码严重依赖于对象地址保持不变,但在.NET中它们不。 .NET要求所有对象都有一个v-表,以便垃圾收集器可以找出该对象的数据类型(因此包含对象指针的内容),但大多数本机类型根本没有v-表。如果不更改布局并破坏与本机代码的兼容性,编译器无法使本机类型与.NET兼容。这会打破目的。因此,虽然编译器可以为本机类型生成元数据,但它对C#没有用处。相反,它使您可以将.NET兼容的类和本机类型一起包含在同一个DLL中,并在它们之间无缝地进行内部调用。

要回答您的其他问题“如何找出在任意.NET程序集内定义了哪些名称空间?”使用装配查看器/反编译器,如dotPeek,.NET反射器等。

+0

感叹。没有魔法。不奇怪。我见过使用P/Invoke的建议,或者将它封装在ActiveX可执行文件中并使用COM Interop。这些工作是否会起作用? –

+0

P/Invoke不会因为你的C++代码是以类的形式出现的。它只适用于具有原始参数类型的自由函数。 COM又名DCOM aka ActiveX是本地代码在类级别共享功能的方式,.NET也可以玩这个游戏。但是将你的本地代码重新编译为COM对象可能比转换(或包装器)更多的工作到'ref class'。因此,如果您还有其他本地消费者,我只能使用COM路线。 –

0

您需要在C++中编写托管包装类。检查this msdn article

其实你不需要编译整个DLL作为/ clr,只有托管的包装。并非所有的C++代码都适用于/ clr,并且存在一个缓慢的下降。