我有一个包含代码的头文件
#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 :(得分:1)
这有点啰嗦,但现在是:
std::string([[nsurl path] UTF8String]);
编辑:好的,也许不是 啰嗦。
答案 1 :(得分:0)
您有几个问题需要解决:
1)为您的C ++ API选择一个字符串类型。您的Windows版本示例使用wstring,它使用wchar_t,在Mac和许多Unix上大小为32位,但在Windows上为16位。此外,wstring用于固定大小的字符串编码,即使Windows滥用它来存储UTF16(这是一种可变长度编码)。您的Mac代码使用字符串,它使用char,在所有平台上都是1个字节。您可以在所有平台上使用UTF8,然后您可以在任何地方使用字符串。它仍然不是固定长度的(即一些字符最多可以编码为4个字节),但它在许多平台上都受支持,所有平台都可以将它们的字符串转换为UTF8。您可以在不同的平台上使用不同的字符串类型,但是您必须使用#if和#endif语句来丢弃代码,以便在每个平台上执行正确的操作。
2)从对象中获取路径。正如您在示例中的注释所述,您首先调用[nsurl path],或者在URL是相对URL的情况下安全[[nsurl absoluteURL] path]。这样你就可以得到完整的路径,而不仅仅是相对的部分。这会为您提供一个NSString对象,然后您可以请求C字符串表示。有几种方法:cString仅适用于ASCII字符串,因此不要使用它。如果您想要UTF8,请使用UTF8String。如果您需要任何其他编码(如UTF16或UTF32),您可以使用dataUsingEncoding:获取NSData对象,然后查看其字节和长度以创建字符串。
3)在使用文件路径的任何地方都要小心。文件系统有一种特殊的“规范”方式来编码文件名。这是必需的,因为Unicode对同一个角色有几种表示形式。例如。 'ä'或'¨a'。 (一种特殊的分音符,可以粘在正常的,而不是我在这里常用的那个)。因此,您需要确保将其转换为规范分解。这就是NSString的-fileSystemRepresentation所用的内容,如果你需要一个C字符串传递到采用文件路径的POSIX API(如果你使用带有NSString的Mac API,它将在透明的情况下为你做到这一点)。