A: 

you may not use c++ object in this manner (as an argument to this NSThread method). if your case is simple (read: few interfaces declared), then you can create a utility (objc) class to handle the message, and to then pass the argument back to the AudioController instance. illustration:

(non-compiled pseudo code follows)

namespace pseudo_object {
template <typename> class reference_counted;
}

@interface MONAudioControllerWorker : NSObject
{
    pseudo_object::reference_counted<AudioController> audioController_;
    std::string asset_;
}

+ (MONAudioControllerWorker *)newMONAudioControllerWorkerWithAudioController:(pseudo_object::reference_counted<AudioController>&)audioController asset:(const std::string&)asset;
- (void)secondaryWorker;

@end

@implementation MONAudioControllerWorker

+ (MONAudioControllerWorker *)newMONAudioControllerWorkerWithAudioController:(pseudo_object::reference_counted<AudioController>&)audioController asset:(const std::string&)asset
{
/* ... */
}

- (void)secondaryWorker
{
    NSAutoreleasePool * pool([NSAutoreleasePool new]);
    audioController_->RotateThread(asset_);
    [pool release];
}

@end
/* static */
ALuint AudioController::PlayStream(pseudo_object::reference_counted<AudioController>& This, const string& asset)
{
/* attach to a thread */
    MONAudioControllerWorker * controller = [MONAudioControllerWorker newMONAudioControllerWorkerWithAudioController:This asset:asset];
    [NSThread detachNewThreadSelector:@selector(secondaryWorker) toTarget:controller withObject:0];
    [controller release];
}

sometimes it is just easier to create an objc class which may contain a simplified (generic) interface for this purpose (i.e. reusable beyond this object), or to use more traditional threading routines (pthreads). if this is the only case in the project, then it should be fine. otherwise, you end up with many utility classes/symbols and much more to maintain. illustration:

@interface MONAudioControllerWrapper : NSObject
{
    AudioController audioController_;
    std::string asset_;
}

+ (MONAudioControllerWrapper *)newMONAudioControllerWrapperWithAsset:(const std::string&)asset;

- (void)playStream;

@end

@implementation MONAudioControllerWrapper

+ (MONAudioControllerWrapper *)newMONAudioControllerWrapperWithAsset:(const std::string&)asset
{
/* ... */
}

- (void)secondaryWorker
{
    NSAutoreleasePool * pool([NSAutoreleasePool new]);
    audioController_->RotateThread(asset_);
    [pool release];
}

- (void)playStream
{
    [NSThread detachNewThreadSelector:@selector(secondaryWorker) toTarget:self withObject:0];
}

@end
Justin
Thanks for the quick reply justin. I will try that out. Looks quite complicated.
John M
you're welcome. if you need 2 classes (as in the above case), it is *often* easier to put the cpp object as an ivar of a objc object.
Justin
Are you implying that i have a global objc object and use that to access the cpp objects.
John M
no, just create an objc object which contains one instance, and create them on demand. the audio engine should all be below the objc interface - if you need to mix various streams or create complex mixers, do it in the cpp bit. see the second code example (updated).
Justin
of course, your needs may vary. you may want to separate the asset_ from the audioController_ in practice. there's not enough detail to specify which is best.
Justin
+1  A: 

You can't do this. It isn't as a simple as "Where do I get the self pointer?" The actual question is, "Where do I get something that can respond to messages?" Because a C++ class can't.

Objective-C classes, objects and methods are completely different things from C++ classes, objects and methods. The fact that the two languages use the same terminology and use the things for similar purposes confuses a lot of people, but to be clear: They are totally different things that work in very different ways in the two languages. Case in point: C++ methods are simply called rather than dispatched based on a selector like Objective-C methods. And C++ classes aren't even objects.

You have two real options here:

  1. Create an Objective-C class that has the behavior you want.

  2. Use a C++ concurrency solution.

Chuck
Can you please provide a snippet implementing C++ concurrency solution. Much interested to learn about it. thanks
John M
@John M: It's not really my forte, but here's an example I found on Stack Overflow: http://antonym.org/2009/05/threading-with-boost---part-i-creating-threads.html
Chuck
A: 

As others have said, you can't use detachThreadWithSelector: passing a C++ object as a target or using a C++ method as the selector.

You have two strategies:

  1. wrap the object and selector with an OBjective-C object and selector e.g.

    myAudioControllerWrapper = [[OCAudioControllerWrapper alloc] initWithRealController: this];
    // need some code to release once thread is complete
    [NSThread detachNewThreadSelector: @selector(wrapperSelector:) target: myAudioControllerWrapper withObject: soundKeyAsNSObject];
    

    and your wrapper selector looks like:

    -(void) wrapperSelector: (id) key
    {
        cppController->rotateThread([key cppObject]);
    }
    
  2. Use some other thread mechanism more in keeping with the C++ paradigm. Grand Central Dispatch might be the one if your platform supports it.

JeremyP