使用C ++中的NSProcessInfo

时间:2016-12-16 12:59:56

标签: c++ macos cocoa foundation

是否可以使用C ++或C中的[[NSProcessInfo processInfo] operatingSystemVersion],我该怎么做?

1 个答案:

答案 0 :(得分:4)

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

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

让我们考虑以下设置:

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

    让我们从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 "?";
        }
    }
    

    请注意getProcessInfoVersion_C是一个C风格的函数,但在其实现中包含了Objective-C代码。

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

    // UseProcessInfoInC.hpp:
    #ifndef UseProcessInfoInC_hpp
    #define UseProcessInfoInC_hpp
    
    class MyCppProcessInfo {
    public:
        void printVersion(void);
    };
    
    #endif /* UseProcessInfoInC_hpp */
    

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

    请注意,这两个文件不包含任何Objective-C-stuff。 最后,让我们试试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]));
        }
    }