简体   繁体   English

在c ++代码中使用objc对象?

[英]Use objc object inside c++ code?

I have an ObjC class called Log. 我有一个名为Log的ObjC类。 In this class I have a public static method call error. 在这个类中,我有一个公共静态方法调用错误。

I want to call this method from my C++ code (if possible like this: Log::error(string);). 我想从我的C ++代码中调用这个方法(如果可能的话,这样:Log :: error(string);)。

I was going around the internet and stack overflow but I found only this: 我在互联网和堆栈溢出,但我发现只有这个:

http://philjordan.eu/article/mixing-objective-c-c++-and-objective-c++ http://philjordan.eu/article/mixing-objective-c-c++-and-objective-c++

and this: 和这个:

Calling Objective-C method from C++ method? 从C ++方法调用Objective-C方法? (I tried to use the first method but I don't know how to create the void *objectiveCObject variable.) (我尝试使用第一种方法,但我不知道如何创建void * objectiveCObject变量。)

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. Log类的头文件中,你需要提供一个C-linkage的回调机制,C ++可以使用它,你需要防止C ++看到Objective-C的东西。 This header can then be shared by both C++ and Objective-C. 然后,此标头可由C ++和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. 另一种方法是提供一个单独的头文件和实现文件,仅供C ++使用,但这会给实现增加更多的麻烦。

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. 根据你的评论,我已经添加了C ++可访问的方法来创建和销毁Objective-C Log对象,但是我确信这样做你必须使用MRR而不是ARC,以便你可以管理生命周期。 So you you will need to compile Log.m with -fobjc-no-arc . 因此,您需要使用-fobjc-no-arc编译Log.m

Log.h: 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: 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: 然后,您的C ++代码应该能够像这样使用Objective-C Log对象:

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. 我可能赞成为Objective-C类创建一个C ++包装类,这样可以更容易地管理对象的生命周期并简化对它的访问。 However I will avoid adding it here as it will likely just complicate something that is already over-complicated. 但是我会避免在这里添加它,因为它可能会使已经过于复杂的东西复杂化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM