Использовать объект objc внутри кода C ++?

0

У меня есть класс ObjC, называемый Log. В этом классе у меня есть общедоступная статическая ошибка вызова метода.

Я хочу вызвать этот метод из моего кода C++ (если это возможно: Log :: error (string);).

Я ходил по интернету и переполнял стек, но я нашел только это:

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

и это:

Вызов метода Objective-C из метода C++? (Я попытался использовать первый метод, но я не знаю, как создать переменную void * objectCObject.)

  • 0
    У меня также есть класс C ++ с именем Log который используется как в C ++, так и в Objective-C ++, и для меня это не было проблемой, так как я реализовал класс с использованием C ++, а не Objective-C ++, который является своего рода наименьшим общим знаменателем два языка. Будет ли этот подход работать для вас?
  • 0
    Я хотел сделать это с помощью кода objc, поскольку я пытаюсь получить больше опыта в нем.
Показать ещё 3 комментария
Теги:
macos
xcode5

1 ответ

2
Лучший ответ

Внутри файла заголовка для класса 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, что упростит управление временем жизни объекта и упростит доступ к нему. Однако я не буду добавлять его сюда, так как это, скорее всего, просто усложнит то, что уже слишком сложно.

  • 0
    Есть ли способ, которым я могу инициировать его в файле .cpp? Если бы вы могли поделиться кодом для него, это будет здорово.
  • 0
    @MartiMarkov Хорошо, я обновил свой ответ. Это на самом деле делает реализацию намного аккуратнее и очевиднее. Обратите внимание на то, что ARC не используется при реализации Log .
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню