Using NSProcessInfo from C++

后端 未结 1 1178
你的背包
你的背包 2021-01-07 02:58

Is it possible to use [[NSProcessInfo processInfo] operatingSystemVersion] from C++ or C and how do I do that?

1条回答
  •  醉梦人生
    2021-01-07 03:15

    In XCode and Objective-C, files with extension .mm are treated as "mixed" in the sense that one single file can contain C++/C notion as well as Objective-C code, and that even C++/C function implementations can access Objective-C classes and send messages to them.

    Such a .mm-files can then provide a trampoline function, i.e. a C-style function that is exposed and can then be used in pure C++/C-files (extension .cpp, where Objective-C code must not occur).

    Let's consider the following setting:

    1. A mixed file ProcessInfoProvider.mm, which calls [[NSProcessInfo processInfo] operatingSystemVersion] and provides the result in a C-style function std::string getProcessInfoVersion_C(),
    2. A Pure cpp-file and a corresponding hpp-file UseProcessInfoInC.cpp/hpp defining a class MyCppProcessInfo, which provides a printVersion()-member function and which uses getProcessInfoVersion_C,
    3. Some other file that instantiates MyCppProcessInfo and calls member function printVersion()

    Let's start with ProcessInfoProvider.mm:

    #import 
    #import 
    #include 
    #include 
    
    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 "?";
        }
    }
    

    Note that getProcessInfoVersion_C is a C-style function but contains objective-C code in it's implementation.

    Then, pure C++ files UseProcessInfoInC.cpp/hpp implement class MyCppProcessInfo:

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

    and

    // UseProcessInfoInC.cpp:
    #include "UseProcessInfoInC.hpp"
    #include 
    
    extern std::string getProcessInfoVersion_C (void);
    
    void MyCppProcessInfo::printVersion(void)
    {
        std::string version = getProcessInfoVersion_C();
    
        std::cout << version;
    }
    

    Note that these two files do not contain any Objective-C-stuff. Finally, let's try out MyCppProcessInfo, e.g. in a function main():

    // File main.mm
    #import 
    #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]));
        }
    }
    

    0 讨论(0)
提交回复
热议问题