2013-08-18 65 views
-1

我正在爲非託管C++庫編寫CLR包裝程序。在C++/CLI代碼中包含來自非託管C++代碼的頭文件

有兩個文件我包括從非託管的lib:

//MyCLIWrapper.h 
#include "C:\PATH\TO\UNMANAGED\Header.h" 
#include "C:\PATH\TO\UNMANAGED\Body.cpp" 

然後我寫CLI實施的非託管庫函數:

//MyCLIWrapper.h 
// includes ... 
void MyCLIWrapper::ManagedFunction() 
{ 
    UnmanagedFunction(); // this function is called successfuly 
} 

但是,如果我的非託管函數包含對其他非託管頭文件中定義的其他函數的調用。這會導致編譯器鏈接錯誤。

如果我將包含添加到定義這些函數的非託管頭文件中,我的錯誤將得到解決。但是,有很多功能,並且需要大量的功能。

有沒有不同的方法來解決這個問題?

編輯: P.S. 我的託管代碼位於單獨的Visual Studio項目(輸出 - DLL)中,編譯設置設置爲/ CLR。非託管代碼位於單獨的Win32項目(輸出 - DLL)中。

此外,經過更多的研究,我得出結論,理論上我可以將我的Win32非託管項目設置爲CLR,並將其中的託管類和頭文件添加爲入口點,然後將它們全部編譯爲單個DLL文件。這可能會解決(?)聯動錯誤。但是,我寧願保留鬆耦合以及將我的非託管項目設置爲CLR可能引發的其他一系列問題。

編輯#2: 說我引用(body.cpp,header.h)的非託管類包含包括該定義是造成問題的功能所需的文件。但是,我的託管代碼沒有選擇位於非託管body.cpp和header.h中的包含。

+0

所以非託管函數?我做了類似於你之前做的事情,但我不記得有這個特殊問題。爲了讓事情順利進行,您更改了哪些Visual Studio項目設置? –

+0

託管代碼和C++/CLI在這裏沒有改變任何東西。一個定義規則與只有您的本地功能的項目完全相同。 –

+0

@BenVoigt我編輯了我的問題:它是兩個獨立的項目,非託管類具有所有的定義和包含,但我的託管項目沒有選擇這些額外的非託管類。 –

回答

4

鏈接器錯誤與編譯器錯誤是不同的一團魚。您忘記記錄您看到的確切鏈接程序錯誤,但是當您使用/ clr生效時編譯代碼時非常常見的問題是非C++成員函數的默認調用約定發生更改。默認值是__clrcall,這是一個爲託管代碼優化的約定。不帶/ clr編譯的函數默認爲__cdecl。這改變了函數名稱被破壞的方式。您在鏈接器錯誤消息中看到了這一點,表明它正在查找__clrcall函數並且找不到它。

您需要使用__cdecl明確聲明.h文件中的函數。或者告訴編譯器這些函數不是託管代碼。這是解決它的最好辦法:

#pragma managed(push, off) 
#include "unmanagedHeader.h" 
#pragma managed(pop) 
1

解決方案是非常簡單的:

  1. 我都添加非託管和託管項目在Visual Studio的單一解決方案。
  2. 將非託管項目的「配置類型」設置爲「靜態庫」(.lib)。
  3. 右鍵單擊託管項目 - >引用 - >添加引用 - >項目 - > - >添加引用。
  4. 然後在我的託管類中,我包含header.h(只),就像我在我的問題中所做的一樣。
  5. 編譯成功!

謝謝

不調用其他非託管函數做工精細