在Log
该类的头文件中,您需要提供一个带有 C 链接的回调机制,该机制可以被 C++ 使用,并且您需要防止 C++ 看到 Objective-C 的东西。然后这个头文件可以被 C++ 和 Objective-C 共享。对此的替代方法是提供单独的头文件和实现文件,仅用于 C++,但是这增加了实现的麻烦。
根据您的评论,我已经添加了 C++ 可访问的方法来创建和销毁 Objective-CLog
对象,但是我确信要让这个工作,您必须使用 MRR 而不是 ARC,以便您可以管理生命周期。所以你需要Log.m
用-fobjc-no-arc
.
日志.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__
日志.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++ 代码应该能够Log
像这样使用 Objective-C 对象:
ObjcLog *logObj = logCreate("/path/to/file.log");
...
logInfo(logObj, "The answer is %d. What is the question?", 42);
...
logDestroy(logObj);
我可能倾向于为 Objective-C 类创建一个 C++ 包装类,这将更容易管理对象的生命周期并简化对它的访问。但是,我将避免在此处添加它,因为它可能只会使已经过于复杂的事情变得复杂。