Ste*_*ner 5

在 XCode 和 Objective-C 中,具有扩展名的文件.mm被视为“混合”,因为单个文件可以包含 C++/C 概念以及 Objective-C 代码,甚至 C++/C 函数实现也可以访问 Objective-C类并向他们发送消息。

这样的.mm-files 然后可以提供一个trampoline 函数,即公开的 C 风格函数,然后可以在纯 C++/C 文件中使用(扩展名.cpp,其中不能出现 Objective-C 代码)。

让我们考虑以下设置:

  1. 一个混合文件ProcessInfoProvider.mm,它[[NSProcessInfo processInfo] operatingSystemVersion]在一个 C 风格的函数中调用并提供结果std::string getProcessInfoVersion_C()
  2. 一个纯 cpp 文件和一个相应的 hpp 文件UseProcessInfoInC.cpp/hpp定义了一个类MyCppProcessInfo,它提供了一个printVersion()-member 函数并使用了getProcessInfoVersion_C
  3. 其他一些实例化MyCppProcessInfo和调用成员函数的文件printVersion()

让我们开始ProcessInfoProvider.mm

#import <Foundation/Foundation.h>
#import <Foundation/NSProcessInfo.h>
#include <string.h>
#include <iostream>

std::string getProcessInfoVersion_C (void) {
    NSProcessInfo *processInfo = [[NSProcessInfo alloc] init];

    // check avaiability of the property operatingSystemVersion (10.10+) at runtime
    if ([processInfo respondsToSelector:@selector(operatingSystemVersion)])
    {
        NSOperatingSystemVersion versionObj = [processInfo operatingSystemVersion];

        char version[500];
        snprintf(version, 500, "Version %ld.%ld.%ld",
                 (long)versionObj.majorVersion,
                 (long)versionObj.minorVersion,
                 (long)versionObj.patchVersion);

        return version;
    }
    else
    {
        // Implement fallback for OSX 10.9 and below
        return "?";
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这getProcessInfoVersion_C是一个 C 风格的函数,但在它的实现中包含目标 C 代码。

然后,纯 C++ 文件UseProcessInfoInC.cpp/hpp实现类MyCppProcessInfo

// UseProcessInfoInC.hpp:
#ifndef UseProcessInfoInC_hpp
#define UseProcessInfoInC_hpp

class MyCppProcessInfo {
public:
    void printVersion(void);
};

#endif /* UseProcessInfoInC_hpp */
Run Code Online (Sandbox Code Playgroud)

// UseProcessInfoInC.cpp:
#include "UseProcessInfoInC.hpp"
#include <iostream>

extern std::string getProcessInfoVersion_C (void);

void MyCppProcessInfo::printVersion(void)
{
    std::string version = getProcessInfoVersion_C();

    std::cout << version;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这两个文件不包含任何 Objective-C 的东西。最后,让我们尝试一下MyCppProcessInfo,例如在一个函数中main()

// File main.mm
#import <UIKit/UIKit.h>
#import "AppDelegate.h"

#include "UseProcessInfoInC.hpp"

int main(int argc, char * argv[]) {
    @autoreleasepool {

        MyCppProcessInfo pi;
        pi.printVersion();

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}
Run Code Online (Sandbox Code Playgroud)