将 C++ 虚拟方法调用接收到 Objective-C++ 应用程序的正确方法是什么?
What's the proper way to receive C++ virtual-method calls into an Objective-C++ application?
我有一个可移植的 C++ 网络代码库,它大量使用抽象和半抽象接口 classes,例如像这样的东西:
// Semi-abstract interface for any C++ object that wants to
// be notified about network events
class INetworkEventReceiver
{
public:
INetworkEventReceiver(INetworkEventGenerator * master)
: m_master (master)
{
m_master->RegisterEventReceiver(this);
}
virtual ~INetworkEventReceiver()
{
m_master->UnregisterEventReceiver(this);
}
// Called by our m_master object whenever a network event happens
// Implemented by subclasses to do something useful.
virtual void NetworkEventReceived(const NetworkEvent & event) = 0;
private:
INetworkEventGenerator * m_master;
};
一切正常。但是,现在有兴趣通过 Objective C++ 在 iOS 应用程序中使用此库。
我的问题是,Objective-C++ 代码实现 "hook methods"(如上面的 NetworkEventReceived(const NetworkEvent & event)
)的最佳方法是什么?我希望 Objective-C++ class 可以简单地 subclass INetworkEventReceiver
并声明它自己的虚拟方法,就像 C++ subclass 那样,但是似乎 Objective-C++ doesn't support that。实现此目标的下一个最佳方法是什么?
您可以将 C++ class 作为 ivar 嵌入到 Objective-C class 中。类似于:
// header:
@interface Receiver : NSObject
@end
// .mm:
// declare any methods with C++ typed parameters or return types here so the header
// can be #imported in Objective-C, not just Obj-C++. This class extension
// can also be moved to an Objective-C++-only header if necessary to get to
// those methods from multiple .mm files.
@interface Receiver()
- (void) receivedNetworkEvent:(const NetworkEvent& event)event;
@end
struct ConcreteReceiver : INetworkEventReceiver
{
__weak Receiver* target;
virtual void NetworkEventReceived(const NetworkEvent& event) override;
};
void ConcreteReceiver::NetworkEventReceived(const NetworkEvent& event)
{
[this->target receivedNetworkEvent:event];
}
@implementation Receiver
{
ConcreteReceiver receiverShim;
}
- (instancetype)init
{
self = [super init];
if (self != nil)
{
self->receiverShim.target = self;
}
return self;
}
- (void) receivedNetworkEvent:(const NetworkEvent& event)event
{
// Do the thing
}
@end
这有点笨拙,尤其是对于较大的界面,但它确实有效。请注意,C++ 对象持有对其包含的 Objective-C 对象的 __weak
引用以避免泄漏。
我有一个可移植的 C++ 网络代码库,它大量使用抽象和半抽象接口 classes,例如像这样的东西:
// Semi-abstract interface for any C++ object that wants to
// be notified about network events
class INetworkEventReceiver
{
public:
INetworkEventReceiver(INetworkEventGenerator * master)
: m_master (master)
{
m_master->RegisterEventReceiver(this);
}
virtual ~INetworkEventReceiver()
{
m_master->UnregisterEventReceiver(this);
}
// Called by our m_master object whenever a network event happens
// Implemented by subclasses to do something useful.
virtual void NetworkEventReceived(const NetworkEvent & event) = 0;
private:
INetworkEventGenerator * m_master;
};
一切正常。但是,现在有兴趣通过 Objective C++ 在 iOS 应用程序中使用此库。
我的问题是,Objective-C++ 代码实现 "hook methods"(如上面的 NetworkEventReceived(const NetworkEvent & event)
)的最佳方法是什么?我希望 Objective-C++ class 可以简单地 subclass INetworkEventReceiver
并声明它自己的虚拟方法,就像 C++ subclass 那样,但是似乎 Objective-C++ doesn't support that。实现此目标的下一个最佳方法是什么?
您可以将 C++ class 作为 ivar 嵌入到 Objective-C class 中。类似于:
// header:
@interface Receiver : NSObject
@end
// .mm:
// declare any methods with C++ typed parameters or return types here so the header
// can be #imported in Objective-C, not just Obj-C++. This class extension
// can also be moved to an Objective-C++-only header if necessary to get to
// those methods from multiple .mm files.
@interface Receiver()
- (void) receivedNetworkEvent:(const NetworkEvent& event)event;
@end
struct ConcreteReceiver : INetworkEventReceiver
{
__weak Receiver* target;
virtual void NetworkEventReceived(const NetworkEvent& event) override;
};
void ConcreteReceiver::NetworkEventReceived(const NetworkEvent& event)
{
[this->target receivedNetworkEvent:event];
}
@implementation Receiver
{
ConcreteReceiver receiverShim;
}
- (instancetype)init
{
self = [super init];
if (self != nil)
{
self->receiverShim.target = self;
}
return self;
}
- (void) receivedNetworkEvent:(const NetworkEvent& event)event
{
// Do the thing
}
@end
这有点笨拙,尤其是对于较大的界面,但它确实有效。请注意,C++ 对象持有对其包含的 Objective-C 对象的 __weak
引用以避免泄漏。