2011-03-08 102 views
3

我有一個項目,我必須連接到一個基於C的庫,並且我無法使用DLLImport從C#獲取函數。我必須使用基於C++/CLI的項目才能使用這些函數。 (更多的故事,但不重要)。Visual C++/CLI - CLR類 - LNK2020錯誤 - 如何解決?

我在10年前學習過C++,所以請原諒我,如果這看起來很天真。
去年我購買了一些關於C++/CLI實現的書籍,並且掌握了一些涉及的內容 - 我只是爲這個項目挖掘了這些書籍。 (我一直是程序員很長一段時間)。

我認爲我最好開始一個小項目示例項目,以熟悉將涉及的內容,確保可以編譯等。我使用Visual Studio 2008 SP1開始了一個項目; Visual C++> CLR>類庫。在項目中 - 我想從DLL中使用託管和本地。所以使用/ clr開關。 我在實際代碼中使用了其他名稱;但是這非常非常接近。 (沒有其他文件或功能,在這一點上)

頁眉:

//myWrapper.h 
#pragma once 
using namespace System; 
namespace myWrapper { 
    public ref class myWrappedService { 
     myWrappedService(); 
     bool Connected(String ^user,String ^password,String ^domain); 
    } 
}; 

而且實現了這一點。

//myWrapper.cpp 
//This is the main DLL file 
#include "stdafx.h" 
#include "myWrapper.h" 
using namespace System; 
public ref class myWrappedService 
    { 
     public: 
      myWrappedService() {} 
      bool Connected(String ^user,String ^password,String ^domain) 
      { 
       //just a simple result to start - no real functionality 
       bool result = false; 
       return result; 
      } 
    }; 

這是代碼 - 編譯但獲取鏈接器錯誤。

錯誤LNK2020:無法解析的令牌(06000002)myWrapper.myWrappedService ::連接

致命錯誤LNK1120:1未解析的外部。

這看起來很簡單 - 我可能會想到C#方法。我期望這很簡單 - 但我不熟悉CLI方法應該看到的內容。 (我花了幾個小時尋找答案,並最終覺得我需要發佈一個問題,可能會得到答案)。

回答

4
namespace myWrapper { 

從那裏出錯了。您的.h文件在該名稱空間內聲明瞭一個類,它的名稱是myWrapper :: myWrappedService。您的.cpp文件聲明另一個不在名稱空間中的類,其名稱爲:: myWrappedService。不同的名稱,編譯器不會抱怨看到同一個類定義了兩次。第一類沒有實現Connected方法,這就是連接器抱怨的原因。

sad_man的片段遭受同樣的缺陷。第一個片段定義:: myWrappedService :: Connected()方法。錯誤的命名空間。第二個片段與您的缺陷具有相同的缺陷。

當您在託管代碼中編寫類庫時,則不需要.h文件。組件中的元數據具有相同的作用,它包含程序集中類型的聲明。您的項目中沒有其他.cpp文件需要該類的聲明,不需要.h。因此,只需在.cpp文件中寫入所有內容:

#include "stdafx.h" 
// Note: header file removed 

using namespace System; 

namespace myWrapper { 

    public ref class myWrappedService 
    { 
    public: 
     myWrappedService() {} 
     void Connect(String ^user, String ^password, String ^domain) 
     { 
      throw gcnew NotImplementedException; 
     } 
    }; 
} 
+0

我試過你的方法 - 連接線抱怨錯誤3149:'System :: String'不能在沒有頂級'^'的情況下使用此類型。我還需要一個返回值來說我連接 - 如果你可以修改你的例子 - 可能會起作用。 – Wolfledge 2011-03-09 01:05:27

+0

我在發佈之前驗證了此代碼已編譯並構建到工作集中。 Connect()的String參數在代碼片段中顯然有一個可見的^,請驗證它的副本。我想你可以弄清楚如何自己改變方法的返回類型。 – 2011-03-09 01:09:02

+0

我的壞 - 錯字 - 並使用我編譯的返回類型。當我用反射器打開DLL時,方法就在那裏。謝謝。 – Wolfledge 2011-03-09 12:44:57

2

你的CPP文件是錯的。對於cpp的使用,頭文件看herehere。 C++/Cli具有相同的標題和cpp文件的概念。其實你的CPP文件是一個頭文件應該是。你

也可以是這樣的:

//myWrapper.h 
#pragma once 
#include "stdafx.h" 
using namespace System; 
namespace myWrapper { 
    public ref class myWrappedService { 
     myWrappedService(); 
     bool Connected(String ^user,String ^password,String ^domain); 
    } 
}; 

//myWrapper.cpp 
//This is the main DLL file 
#include "stdafx.h" 
#include "myWrapper.h" 
using namespace System; 
namespace myWrapper 
{ 
    myWrappedService::myWrappedService() {} 
    bool myWrappedService::Connected(String ^user,String ^password,String ^domain) 
    { 
     bool result = false; 
     return result; 
    } 
} 

或像這樣(爲您的情況下,一個頭):

//myWrapper.h 
//This is the main DLL file 
#include "myWrapper.h" 
using namespace System; 
namespace myWrapper 
{ 
public ref class myWrappedService 
    { 
     public: 
      myWrappedService() {} 
      bool Connected(String ^user,String ^password,String ^domain) 
      { 
       //just a simple result to start - no real functionality 
       bool result = false; 
       return result; 
      } 
    }; 
} 
    // Remember? this was your cpp. 

編輯:我已經忘記了命名空間。但我認爲你應該知道頭文件和cpp文件是什麼。

+0

我試過你的第一個例子 - 在代碼庫上有實際名稱 - 沒有工作。然後我使用這些示例名稱創建了一個新項目 - 同樣的問題(甚至沒有編譯)。我想你正試圖指出標題和實現之間的分割。 – Wolfledge 2011-03-09 00:16:56

+0

然後我嘗試了你的「僅頭部」方法 - 它可以編譯和鏈接 - 但是在DLL中指向反射器顯示該方法從不出現。 – Wolfledge 2011-03-09 00:18:09