2016-02-29 48 views
0

我必須創建一個SQLite數據庫使用System.Data.SQLite和使用C++/CLI但我遇到問題。不幸的是,使用C#不是一種選擇,如果它沒有問題的話。 (請不要建議我不要使用C++/CLI,它不是這個項目的一個選項。)預處理器使函數名稱unaccessabel

在C#中,下面的代碼沒有任何問題。

using System.Data.SQLite; 

void CreateDb(String file) 
{ 
    SQLiteConnection.CreateFile(file); 
} 

C++/CLI中的等效代碼並非沒有問題。

using namespace System::Data::SQLite; 

void CreateDb(System::String ^file) 
{ 
    SQLiteConnection::CreateFile(file); // error C2039 
} 

爲C2039確切的錯誤TXT是: //錯誤C2039: 'CreateFileA的':是不是成員 '系統::數據:: SQLite的:: SQLiteConnection'

如果我坐在的CreateFile的定義,仔細一看,我得到以下選擇

#define CreateFile CreateFileW - c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\WinBase.h(9292) 
#define CreateFile CreateFileA - c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\WinBase.h(9294) 

導致以下行WINBASE.H

#ifdef UNICODE 
#define CreateFile CreateFileW 
#else 
#define CreateFile CreateFileA 
#endif // !UNICODE 

Microsoft SDK混淆了我需要的確切名稱,而SQLite不提供給我CreateFile [AW]版本。 所以我在調用SQLiteConnection.CreateFile(文件)的代碼之前試過這個,我這樣做是孤立的,這樣其他代碼就會受到它的影響。

#ifdef CreateFile 
#undef CreateFile 
#endif 

它解決了我的問題(目前),但這有多安全?

有沒有更好的方法來解決這個問題?

您的建議是非常感謝。

回答

2

#undef是我一直處理這個問題的方式。

這有多安全?

這是安全的。

如果您有其他名稱衝突,您可能再次遇到此問題。由於這種名稱衝突導致的編譯錯誤很容易診斷,因爲您知道要查找的內容,因此如果需要,可以輕鬆添加其他#undef指令。

如果您需要撥打Win32 CreateFile,您需要明確鍵入CreateFileACreateFileW,但這不是一件大麻煩事。

有沒有更好的方法來解決這個問題?

是的,但並非總是可行。

更好的方法是在您使用SQLite的文件中不要使用#include <Windows.h>。這完全避免了這個問題。但是,並不總是可以像這樣組織程序,所以#undef通常是解決方案。


(這在下一段並不適用於您的情況使用SQLite:您正在使用的託管版本,所以沒有此頭下位適用於C++,其中包括庫頭庫我包括。這是爲了完整性,以防有人編寫普通的C++)。

要注意的另外一件事是#include -ing庫頭文件之前的Windows頭文件。在這種情況下,類定義本身將有CreateFile重命名爲CreateFileA。如果你使用#undef,你會得到與你展示的相反的錯誤。您可以保留#define,這有時會結束工作,但這很脆弱,所以我會避免這種情況。我在一個C++應用程序中遇到過一次MFC頭文件:更改後的方法名稱到處都是,甚至Intellisense都顯示名稱以「A」結尾。它仍然工作,因爲vTable已在MFC DLL中初始化,所以在調用應用程序中所有重要的是vTable指出了正確的方法,這是。)