2014-02-27 32 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,它将为您透明地进行操作)。