Wrapping Objective C in Objective c++/c++
I've got a c++ app written using Boost/WXWidgets, targeting Windows and Mac OSX. However, I've got one issue that I can't solve using these libraries. My solution requires me to wrap an Objective C class so that I can call it from one of my c++ modules.开发者_开发问答 My research so far tells me that I need to use Objective C++ written into source files with a .mm extension, allowing XCode to treat the file as a mix of Objective C and c++. I've found lots of articles detailing how to wrap c++ so that it can be called from ObjectiveC, but nothing that gives any detail on the reverse. Any links to articles or, better still, a worked example, would be greatly appreciated.
If you want a reusable pure C++ wrapper around an Objective C class, the Pimpl idiom works pretty well. The Pimpl idiom will make it so that there is no Objective C / Cocoa stuff visible in the header file that will be included by pure C++ code.
// 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];
}
Just mix it (but don't forget setting up the pool). It works.
// obj-c code, in .mm file
void functionContainingObjC(){
NSAutoreleasePool*pool=[[NSAutoreleasePool alloc] init];
[lots of brackets!];
[pool release];
}
// c++ code, in .cc file
functionContainingObjC();
objc provides c interfaces for the basic interfaces and types (#include <objc/headers_you_need.h>
. therefore, you can use these interfaces in pure c/c++ TUs. then include libs like Foundation or AppKit in the mm and use objc types and messaging in the implementation.
the following is a very basic interface which is not typesafe, but i encourage you to make it typesafe for the objc type you are wrapping. this should be enough to get you started in the right direction.
// .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];
}
精彩评论