简体   繁体   English

从C ++在Mac OSX上启动一个打开的对话框

[英]Launching an open dialog on Mac OSX from C++

I have a header file that contains the code 我有一个包含代码的头文件

#ifndef PLATFORM_DEPENDENCE
#define PLATFORM_DEPENDENCE

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

#endif

WindowsFunctions.h: 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

and MacFunctions.h: 和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

The WindowsFunctions.cpp is already implemented, and works. WindowsFunctions.cpp已经实现,并且可以工作。 How would I do it for Mac? 我该怎么做Mac? I have written a method that opens up an open dialog, but I have no idea how to return the data to where it was called in C++. 我编写了一个方法来打开一个打开的对话框,但我不知道如何将数据返回到C ++中调用它的位置。

This is the code that opens the dialog: 这是打开对话框的代码:

#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;
}

How would I do this, or am I approaching the problem in a wrong way? 我该怎么做,或者我是以错误的方式处理问题?

It's a bit long-winded, but here it is: 这有点啰嗦,但这里是:

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

Edit: Ok, so maybe not that long-winded. 编辑:好的,也许不是那么啰嗦。

You have several problems to solve: 您有几个问题需要解决:

1) Pick one string type for your C++ API. 1)为您的C ++ API选择一种字符串类型。 Your example of the Windows version uses wstring, which uses wchar_t, which is 32-bit in size on Mac and many Unixes, but 16 bits long on Windows. 您的Windows版本示例使用wstring,它使用wchar_t,在Mac和许多Unix上大小为32位,但在Windows上为16位。 Also, wstring is intended for fixed-size string encodings, even though Windows abuses it to store UTF16 (which is a variable-length encoding). 此外,wstring用于固定大小的字符串编码,即使Windows滥用它来存储UTF16(这是一种可变长度编码)。 Your Mac code uses string, which uses char, which is 1 byte on all platforms. 您的Mac代码使用字符串,它使用char,在所有平台上都是1个字节。 You could use UTF8 on all platforms, then you can use string everywhere. 您可以在所有平台上使用UTF8,然后您可以在任何地方使用字符串。 It's still not fixed-length (ie some characters can be encoded in up to 4 bytes), but it's supported on many platforms and all of them can convert their strings to UTF8. 它仍然不是固定长度的(即一些字符最多可以编码为4个字节),但它在许多平台上都受支持,并且所有平台都可以将其字符串转换为UTF8。 You can use different string types on different platforms, but then you'll have to litter your code with #if and #endif statements to do the right thing on each platform. 您可以在不同的平台上使用不同的字符串类型,但是您必须使用#if和#endif语句来丢弃代码,以便在每个平台上执行正确的操作。

2) get the path out of the object. 2)从对象中获取路径。 As your comment in the example says, you do this by calling [nsurl path] first, or to be safe [[nsurl absoluteURL] path] in case the URL was a relative URL. 正如您在示例中的注释所述,您首先调用[nsurl path],或者在URL是相对URL的情况下安全[[nsurl absoluteURL] path]。 That way you get the full path, and not just the relative part. 这样你就可以得到完整的路径,而不仅仅是相对的部分。 That gives you an NSString object, which you can then ask for a C string representation. 这会为您提供一个NSString对象,然后您可以请求C字符串表示。 There are several methods: cString only works for ASCII strings, so don't use that. 有几种方法:cString仅适用于ASCII字符串,因此不要使用它。 If you want UTF8, use UTF8String. 如果您想要UTF8,请使用UTF8String。 If you want any other encoding (like UTF16 or UTF32), you can use dataUsingEncoding: to get an NSData object, then look at its bytes and length to create a string. 如果您需要任何其他编码(如UTF16或UTF32),您可以使用dataUsingEncoding:获取NSData对象,然后查看其字节和长度以创建字符串。

3) Be careful wherever you use file paths. 3)在使用文件路径的任何地方都要小心。 The file system has a special 'canonical' way of encoding a file name. 文件系统有一种特殊的“规范”方式来编码文件名。 That's needed, because Unicode has several representations for the same character. 这是必需的,因为Unicode对同一个角色有几种表示形式。 Eg 'ä' or '¨a'. 例如'ä'或'¨a'。 (a special diaeresis character that gets glued onto a normally, not the regular one I'm using here). (一种特殊的分音符,可以粘在正常的,而不是我在这里常用的那个)。 So you need to make sure you transform it to that canonical decomposition. 因此,您需要确保将其转换为规范分解。 That's what NSString's -fileSystemRepresentation is for if you need a C string to pass into POSIX API that takes a file path (if you use Mac API that takes an NSString, it will do that for you transparently under the hood). 这就是NSString的-fileSystemRepresentation所用的内容,如果你需要一个C字符串传递到采用文件路径的POSIX API(如果你使用带有NSString的Mac API,它会透明地为你做这件事)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM