macos — Использование NSProcessInfo из переполнения стека

Можно ли использовать [[NSProcessInfo processInfo] operatingSystemVersion] из C ++ или C и как мне это сделать?

2

Решение

В XCode и Objective-C файлы с расширением .mm считаются «смешанными» в том смысле, что один файл может содержать понятие C ++ / C, а также код Objective-C, и что даже реализации функций C ++ / C могут получать доступ к классам Objective-C и отправлять им сообщения.

Такой .mm-files может затем обеспечить функцию батута, то есть функцию в стиле 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()функция -член и которая использует 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 "?";
}
}

Обратите внимание, что getProcessInfoVersion_C является функцией в стиле C, но в ее реализации содержится код target-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.
Наконец, давайте попробуем 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]));
}
}
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]