在Objective c ++ / c ++中包装Objective C

时间:2011-08-20 15:33:29

标签: c++ xcode macos

我有一个使用Boost / WXWidgets编写的c ++应用程序,针对Windows和Mac OSX。但是,我有一个问题,我无法使用这些库解决。我的解决方案要求我包装一个Objective C类,以便我可以从我的一个c ++模块中调用它。到目前为止,我的研究告诉我,我需要使用带有.mm扩展名的源文件编写的Objective C ++,允许XCode将文件视为Objective C和c ++的混合。我发现了很多文章,详细介绍了如何包装c ++以便可以从ObjectiveC调用它,但没有任何内容反过来提供任何细节。任何文章的链接,或者更好的是,一个有用的例子,将不胜感激。

3 个答案:

答案 0 :(得分:4)

如果你想在Objective C类周围使用可重用的纯C ++包装器,那么Pimpl idiom的效果非常好。 Pimpl习惯用法将使得头文件中没有可见的C / Cocoa东西可以包含在纯C ++代码中。

// FooWrapper.hpp

// Absolutely no Cocoa includes or types here!

class FooWrapper
{
public:
    int bar();

private:
    struct Impl; // Forward declaration
    Impl* impl;
};


// FooWrapper.mm

@import "FooWraper.hpp"
@import "Foundation/NSFoo.h"

struct FooWrapper::Impl
{
    NSFoo* nsFoo;
};

FooWrapper::FooWrapper() : impl(new Impl)
{
    impl->nsFoo = [[NSFoo alloc] init];
}

FooWrapper::~FooWrapper()
{
    [impl->nsFoo release];
    delete impl;
}

int FooWrapper::bar()
{
    return [impl->nsFoo getInteger];
}

答案 1 :(得分:2)

混合它(但不要忘记设置池)。它有效。

 // obj-c code, in .mm file
 void functionContainingObjC(){
        NSAutoreleasePool*pool=[[NSAutoreleasePool alloc] init]; 
        [lots of brackets!];
        [pool release];
 }

 // c++ code, in .cc file
 functionContainingObjC();

答案 2 :(得分:1)

objc为基本接口和类型(#include <objc/headers_you_need.h>提供了c接口。因此,您可以在纯c / c ++ TU中使用这些接口。然后在mm中包含像Foundation或AppKit这样的库,并使用objc类型和消息传递在实施中。

以下是一个非常基本的接口,它不是类型安全的,但我鼓励你为你要包装的objc类型设置类型安全。这应该足以让你开始朝着正确的方向前进。

// .hpp
namespace MON {
// could be an auto pointer or a dumb pointer; depending on your needs
    class t_MONSubclassWrapper {
    public:
// usual stuff here...

// example wrapper usage:
        void release();
    private:
        id d_objcInstance;
    };
} /* << MON */

// .mm
...
#include <Foundation/Foundation.h>

MON::t_MONSubclassWrapper::t_MONSubclassWrapper() :
  d_objcInstance([[MONSubclass alloc] init]) {
}
...
void MON::t_MONSubclassWrapper::release() {
    [d_objcInstance release];
}