У меня есть класс ObjC, называемый Log. В этом классе у меня есть общедоступная статическая ошибка вызова метода.
Я хочу вызвать этот метод из моего кода C++ (если это возможно: Log :: error (string);).
Я ходил по интернету и переполнял стек, но я нашел только это:
http://philjordan.eu/article/mixing-objective-c-C++-and-objective-C++
и это:
Вызов метода Objective-C из метода C++? (Я попытался использовать первый метод, но я не знаю, как создать переменную void * objectCObject.)
Внутри файла заголовка для класса Log
вам необходимо предоставить механизм обратного вызова с C-linkage, который может использоваться C++, и вам нужно защититься от C++, видя объект Objective-C. Затем этот заголовок может совместно использоваться как C++, так и Objective-C. Альтернативой этому является предоставление отдельного файла заголовка и файла реализации исключительно для использования C++, однако это добавляет больше возможностей для реализации.
В соответствии с вашим комментарием я добавил доступные C++ методы создания и уничтожения объекта Objective-C Log
, однако я уверен, что для этого вам придется использовать MRR, а не ARC, чтобы вы могли управлять временем жизни, Итак, вам нужно будет скомпилировать Log.m
с -fobjc-no-arc
.
Log.h:
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#else // !__OBJC__
#include <stdarg.h>
// And maybe other C++ headers...
#endif // __OBJC__
typedef void *ObjcLog;
#ifdef __cplusplus
extern "C" {
#endif
extern ObjcLog *logCreate(const char *filename);
extern void logDestroy(ObjcLog *logObj);
extern void logInfo(ObjcLog *logObj, const char *msg, ...);
extern void logError(ObjcLog *logObj, const char *msg, ...);
#ifdef __cplusplus
} // extern "C"
#endif
#ifdef __OBJC__
@interface Log : NSObject {
// stuff
}
// Other stuff
@end
#endif // __OBJC__
Log.m:
#import "Log.h"
ObjcLog *logCreate(const char *filename) {
// Assumes [Log initWithFilename:]
Log *log = [[Log alloc] initWithFilename:[NSString stringWithUTF8String:filename]];
return (ObjcLog *)log;
}
void logDestroy(ObjcLog *logObj) {
Log *log = (Log *)logObj;
[log release];
}
void logInfo(ObjcLog *logObj, const char *msg, ...) {
char buffer[8192];
va_list va;
va_start(va, msg);
vsprintf(buffer, msg, va);
va_end(va);
Log *log = (Log *)logObj;
// Assumes [Log info:]
[log info:[NSString stringWithUTF8String:buffer]];
}
void logError(ObjcLog *logObj, const char *msg, ...) {
char buffer[8192];
va_list va;
va_start(va, msg);
vsprintf(buffer, msg, va);
va_end(va);
Log *log = (Log *)context;
// Assumes [Log error:]
[log error:[NSString stringWithUTF8String:buffer]];
}
@implementation Log
...
@end
Затем ваш C++ код должен использовать объект Objective-C Log
следующим образом:
ObjcLog *logObj = logCreate("/path/to/file.log");
...
logInfo(logObj, "The answer is %d. What is the question?", 42);
...
logDestroy(logObj);
Я бы предпочел создать класс оболочки C++ для класса Objective-C, что упростит управление временем жизни объекта и упростит доступ к нему. Однако я не буду добавлять его сюда, так как это, скорее всего, просто усложнит то, что уже слишком сложно.
Log
.
Log
который используется как в C ++, так и в Objective-C ++, и для меня это не было проблемой, так как я реализовал класс с использованием C ++, а не Objective-C ++, который является своего рода наименьшим общим знаменателем два языка. Будет ли этот подход работать для вас?