Я могу разделить C++ основная функция и классы от Objective C и/или стандартных программ C в компиляции и ссылке?

У меня есть маленькое приложение C++, которое я импортировал классы Objective C. Это работает Objective C ++ файлы, .mm, но любой файл C++, который включает заголовок, который может закончиться включая некоторый заголовок Objective C, должен быть переименован к .mm расширению для надлежащих драйверов GCC.

Существует ли способ записать или обертку чисто C++ для классов Objective C, или я могу выделить объекты Objective C так или иначе и просто связать их отдельно? Возможно, даже если классы Objective C стали небольшой библиотекой, которую я мог бы статически повторно связать во время компиляции?

Проблема состоит в том, что этот код является межплатформенным, и более трудно скомпилировать в системах, которые обычно не используют Objective C (т.е. не Mac). Даже при том, что команды препроцессора ограничивают любую реализацию кода Objective C Windows или Linux, исходный код все еще имеет .mm расширения, и GCC все еще рассматривает код как Objective C ++.

6
задан mike_b 9 February 2010 в 05:17
поделиться

2 ответа

Обычно вы просто оборачиваете свои классы Objective-C классами C ++, например, использование непрозрачных указателей и переадресация вызовов методов C ++ методам Objective-C.

Таким образом, ваши переносимые исходные коды C ++ никогда не должны видеть никаких включений Objective-C, и в идеале вам нужно только заменить файлы реализации для оболочек на разных платформах.

Пример:

// c++ header:
class Wrapper {
    struct Opaque;
    Opaque* opaque;
    // ...
public:
    void f();
};

// Objective-C++ source on Mac:
struct Wrapper::Opaque {
    id contained;
    // ...
};

void Wrapper::f() {
    [opaque->contained f];
}

// ...
3
ответ дан 17 December 2019 в 04:46
поделиться

Да, это легко возможно, в обоих направлениях, если вы знаете несколько приемов:

1) Тип "id" фактически определен в простом заголовке C. Таким образом, вы можете сделать следующее:

В заголовке:

#include <objc/objc.h>

class MyWindow
{
public:
    MyWindow();
    ~MyWindow();
protected:
    id        mCocoaWindow;
};

В вашей реализации (.mm):

#include "MyWindow.h"
#include <Cocoa/Cocoa.h>

MyWindow::MyWindow()
{
    mCocoaWindow = [[NSWindow alloc] init];
}

MyWindow::~MyWindow()
{
    [mCocoaWindow release];
    mCocoaWindow = nil;
}

2) Есть две константы препроцессора, которые вы можете использовать для исключения кода, специфичного для C ++ / ObjC, когда исходный файл включает их, что является одним из двух, но не ObjC ++:

#if __OBJC__
// ObjC code goes here.
#endif /* __OBJC__*/

#if __cplusplus
// C++ code goes here.
#endif

Просто будьте осторожны, вы не можете просто добавить / удалить ivars или виртуальные методы с помощью #ifdef, который создаст два класса с разными макетами памяти и сделает ваше приложение сбой очень странными способами.

3) Вы можете использовать указатель на структуру без объявления ее содержимого:

В вашем заголовке:

@interface MyCppObjectWrapper : NSObject
{
    struct MyCppObjectWrapperIVars    *ivars;    // This is straight ObjC, no ++.
}

@end

В вашем файле реализации (.mm):

struct MyCppObjectWrapperIVars
{
    std::string    myCppString1;
    std::string    myCppString2;
    std::string    myCppString3;
};

@implementation MyCppObjectWrapper

-(id)  init
{
    if(( self = [super init] ))
    {
        ivars = new MyCppObjectWrapperIVars;
    }

    return self;
}

-(void) dealloc
{
    delete ivars;
    ivars = NULL;

    [super dealloc];
}

@end

Это сделает ваш заголовок простым стандартным C или ObjC , в то время как ваш файл реализации получает конструкторы / деструкторы всех вызываемых ivar без необходимости создавать / удалять каждый из них как объект в куче.

Все это касается только Mac, но это будет означать, что вы можете убрать материал ObjC из своих заголовков или, по крайней мере, заставить его компилироваться при использовании из кроссплатформенных клиентских файлов реализации Mac вашего C ++. уровень переносимости.

2
ответ дан 17 December 2019 в 04:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: