C++ iPhone:从C++;对象
我正在为iPhone编写一个游戏。几乎所有的代码都是用C++编写的。现在我想使用NSThread创建一个新线程(我想使用runLoop) <> P> Objy-C和C++,如果代码是用.mm文件编写的,我就可以了。 问题是,创建NSThreadC++ iPhone:从C++;对象,c++,objective-c,multithreading,nsthread,C++,Objective C,Multithreading,Nsthread,我正在为iPhone编写一个游戏。几乎所有的代码都是用C++编写的。现在我想使用NSThread创建一个新线程(我想使用runLoop) P> Objy-C和C++,如果代码是用.mm文件编写的,我就可以了。 问题是,创建NSThread NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:@selector(workerThreadFunction:) object:nil]; [myThread start
NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:@selector(workerThreadFunction:) object:nil];
[myThread start];
我需要传递“自我”(据我所理解),Objul-C“ID”,C++对象不是Objto-C对象。
>——在C++应用中有没有使用NStWORE的方法呢?还是我被迫使用pTrx+< /P>
谢谢 > P>不能从Objc类派生C++类,反之亦然。设计一个包装器Objc对象,它将实例化并调用(但不继承)C++。这通常被称为“遏制和授权” 或者可以使用POSIX线程而不是NSThread
我能不能创建一个ObjuleC对象,在它的构造函数中,C++函数指针作为它后来调用的参数?p> 当然。像这样:
//The C++ base
class ThreadBase
{
virtual void Run() = 0;
};
typedef ThreadBase * (*ThreadCreator)();
//The ObjC wrapper
@interface ThreadStarter:NSObject
{
ThreadCreator TheCreator;
}
-(void)Run;
-(id)init:(ThreadCreator)tc;
@end
@implementation ThreadStarter
-(id)init:(ThreadCreator)tc
{
TheCreator = tc;
return [super init];
}
-(void)Run
{
(*TheCreator)()->Run();
}
@end
//
class MyThread: public ThreadBase
{
//...
};
ThreadBase *MyThreadCreator()
{
return new MyThread();
}
//And finally usage
ThreadStarter *tc = [[ThreadStarter alloc]init:MyThreadCreator];
NSThread* myThread = [[NSThread alloc] initWithTarget:tc selector:@selector(Run) object:nil]; [myThread start];
它由creator函数参数化,因为您需要它。但是您也可以按类进行参数化。对于我先前答案的C++风格的重新表述:
//The C++ base
class ThreadBase
{
virtual void Run() = 0;
};
//The ObjC wrapper
@interface ThreadStarter:NSObject
{
ThreadBase *TheThread;
}
-(void)Run;
-(id)init:(ThreadBase)tb;
@end
@implementation ThreadStarter
-(id)init:(ThreadBase)tb
{
TheThread = tb;
return [super init];
}
-(void)Run
{
TheThread->Run();
}
@end
//
class MyThread: public ThreadBase
{
//...
};
//And finally usage
MyThread *Thread = new MyThread();
ThreadStarter *tc = [[ThreadStarter alloc]init:Thread];
NSThread* myThread = [[NSThread alloc] initWithTarget:tc selector:@selector(Run) object:nil];
[myThread start];
这样更干净,伊姆霍。如果您坚持认为线程启动例程是atrbitrary类中的任意函数,而不是您创建的函数,那么以下是您的答案:
class MyThread: public ThreadBase, public MyOtherObject
{
void Run()
{
DoWork(); //Function defined in MyOtherObject
}
}
你看,如果你想通过成员函数来参数化,你必须通过函数和类来参数化。在C++中,类不能是运行时变量。 “我能不知何故创建一个ObjuleC对象,它在构造函数中以C++函数指针作为它稍后调用的参数”< /P> 是的,但是很难看 首先,定义回调基类和模板版本。这可以进入一个通用的.h文件,该文件可以从.cpp和.mm文件中包含。还要定义一个基本的
CThread
类:
// Thread.h
#pragma once
#include <objc/objc.h> // for a cpp compatible definition of id
class Callback{
public:
virtual void operator()(void)=0;
};
template<class T>
class ClassCallback : public Callback {
T* _classPtr;
typedef void(T::*fncb)(void);
fncb _cbProc;
public:
ClassCallback(T* classPtr,fncb cbProc):_classPtr(classPtr),_cbProc(cbProc){}
virtual void operator()(void){
(_classPtr->*_cbProc)();
}
};
class CThread {
id _thread;
public:
void Start(Callback* cb);
};
然后,在应用程序的cpp文件中,您可以:
// MyClass.cpp (doesn't even have to be .mm)
#include "Thread.h"
class MyClass {
CThread _myThread;
void SomeArbMethod(){
}
public:
MyClass(){
_myThread.Start( new ClassCallback<MyClass>(this,&MyClass::SomeArbMethod));
}
};
//MyClass.cpp(甚至不必是.mm)
#包括“Thread.h”
类MyClass{
CThread\u myThread;
void方法(){
}
公众:
MyClass(){
_Start(新类回调(this,&MyClass::SomeArbMethod));
}
};
>你不需要传递自,你可以通过任何ObjuleC对象。所以它意味着我不能将TrimEngEngEt函数定义为C++对象的成员函数。不,但是你可以用C++对象初始化一个虚拟Objy-C对象,然后,我可以创建一个ObjuleC对象,它在构造函数中把C++函数指针作为一个它后来调用的参数,我不打算继承NStWords-我用一个WorkthTead函数来初始化NStTrand对象,如在提问的意思中所示,你不能从C++派生一个C++类。NSObject。这是id/选择器对存在所必需的。实际上,我指的是指向要用作threadfunction的memberfunction的functionpointer(而不是指向返回“ThreadBase”对象的函数的functionpointer)。无论如何-您以前的版本看起来相当不错,但我有一个问题:-(void)执行{obj->func(arguments);}
因为obj是void类型*这就是成员函数指针的问题-它们只有在您知道它们来自哪个类(或者使用非常难看的类型转换)时才有意义。请不要混淆函数指针和成员函数指针-它们完全不同。这不是ObjC,您可以在不知道对象的类的情况下调用对象上的方法。我仍然推荐一个基类,它有一个抽象的参数化方法——这就是C++方法。
// MyClass.cpp (doesn't even have to be .mm)
#include "Thread.h"
class MyClass {
CThread _myThread;
void SomeArbMethod(){
}
public:
MyClass(){
_myThread.Start( new ClassCallback<MyClass>(this,&MyClass::SomeArbMethod));
}
};