2013-06-20 65 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,並且存在一個緩慢的下降。