Within the header file for the Log
class you need to provide a callback mechanism with C-linkage that can be used by C++ and you need to guard against C++ seeing the Objective-C stuff. This header can then be shared by both C++ and Objective-C. An alternative to this is to provide a separate header file and implementation file solely for the use of C++, however that adds more cruft to the implementation.
As per your comment, I have added C++ accessible methods to create and destroy the Objective-C Log
object, however I'm certain for this to work you'll have to use MRR rather than ARC so that you can manage the lifetime. So you you will need to compile Log.m
with -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
Your C++ code should then be able to use the Objective-C Log
object like this:
ObjcLog *logObj = logCreate("/path/to/file.log");
...
logInfo(logObj, "The answer is %d. What is the question?", 42);
...
logDestroy(logObj);
I would probably favour the creation of a C++ wrapper class for the Objective-C class, which will make it easier to manage the lifetime of the object and simplify access to it. However I will avoid adding it here as it will likely just complicate something that is already over-complicated.