2014-02-27 58 views
2

在Mac OSX上打開的對話我有一個包含代碼啓動從C++

#ifndef PLATFORM_DEPENDENCE 
#define PLATFORM_DEPENDENCE 

#define USE_MAC 
#include "WindowsFunctions.h" 
#include "MacFunctions.h 

#endif 

WindowsFunctions.h頭文件:

#ifndef WINTRANSFERINCLUDE 
#define WINTRANSFERINCLUDE 
#ifdef USE_WINDOWS 

#include <string> 
#include <boost/shared_ptr.hpp> 

using namespace std; 

#include <windows.h> 
#include <Shlobj.h> 

boost::shared_ptr<wstring> browseFolder(); 
boost::shared_ptr<vector<wstring>> getFilesInDirRecursiveImplementation(boost::shared_ptr<vector<wstring>> dirs, boost::shared_ptr<vector<wstring>> files); 

#endif 
#endif 

和MacFunctions.h:

#ifndef MACTRANSFERINCLUDE 
#define WACTRANSFERINCLUDE 
#ifdef USE_MAC 

#include <string> 
#include <boost/shared_ptr.hpp> 

using namespace std; 

boost::shared_ptr<wstring> browseFolder(); 
boost::shared_ptr<vector<wstring>> getFilesInDirRecursiveImplementation(boost::shared_ptr<vector<wstring>> dirs, boost::shared_ptr<vector<wstring>> files); 

#endif 
#endif 

WindowsFunctions.cpp已經實現,並且可以工作。我將如何爲Mac做到這一點?我寫了一個打開對話框的方法,但我不知道如何將數據返回到它在C++中調用的位置。

這是打開的對話框代碼:

#import <Cocoa/Cocoa.h> 
#include <string> 

std::string* path() { 
    NSOpenPanel *op = [NSOpenPanel openPanel]; 
    if ([op runModal] == NSOKButton) { 
      NSURL *nsurl = [[op URLs] objectAtIndex:0]; 
      // nsurl.path contains the NSString I want to return as std::string 
    } 
    // ??? 
    return something; 
} 

我將如何做到這一點,還是我在一個錯誤的方式接近問題?

回答

0

這是一個有點囉嗦,但在這裏它是:

std::string([[nsurl path] UTF8String]); 

編輯:好了,也許不是囉嗦。

+0

這不會編譯。 NSURL沒有UTF8String方法。另外,他上面的API使用wstring,而不是字符串,所以你需要導出爲UTF16,而不是UTF8。(它最初說[[nsurl absoluteURL] UTF8String]) – uliwitness

+0

@uliwitness:答案已更新,但所提供的函數使用std :: string,以覆蓋其他注意事項。 –

+0

這實際上很整潔! – DonAlonzo

0

您有幾個問題需要解決:

1)拿起一個字符串類型的C++ API。您的Windows版本示例使用wstring,它使用wchar_t,它在Mac和許多Unix上的大小爲32位,但在Windows上長16位。此外,即使Windows濫用它來存儲UTF16(這是一種可變長度編碼),wstring也適用於固定大小的字符串編碼。您的Mac代碼使用字符串,該字符串使用char,在所有平臺上均爲1字節。你可以在所有平臺上使用UTF8,然後你可以在任何地方使用字符串。它仍然不是固定長度的(即某些字符可以編碼爲4個字節),但它在很多平臺上都受支持,並且它們都可以將它們的字符串轉換爲UTF8。您可以在不同的平臺上使用不同的字符串類型,但是您必須使用#if和#endif語句來清理代碼,才能在每個平臺上做正確的事情。

2)獲取對象的路徑。正如您在示例中所說的,您可以先通過調用[nsurl path]來實現此目的,或者在URL爲相對URL的情況下爲安全[[nsurl absoluteURL]路徑]。這樣你就可以得到完整的路徑,而不僅僅是相對的部分。這給你一個NSString對象,然後你可以請求一個C字符串表示。有幾種方法:cString只適用於ASCII字符串,所以不要使用它。如果你想要UTF8,使用UTF8String。如果你想要任何其他編碼(如UTF16或UTF32),你可以使用dataUsingEncoding:來獲得一個NSData對象,然後查看它的字節和長度來創建一個字符串。

3)使用文件路徑時要小心。文件系統具有編碼文件名的特殊「規範」方式。這是必要的,因爲Unicode對同一個字符有幾個表示。例如。 'ä'或'¨a'。 (一個特殊的diaeresis字符粘在一個正常的,而不是我在這裏使用的常規字符)。所以你需要確保你將它轉換成規範分解。這就是NSString的-fileSystemRepresentation適用於如果需要將C字符串傳遞到需要文件路徑的POSIX API(如果您使用帶有NSString的Mac API,它將爲您透明地進行操作)。