将事件从C提升到C#(iOS到Unity) [英] Raise events from C to C# (iOS to Unity)
本文介绍了将事件从C提升到C#(iOS到Unity)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想在Unity中注册事件,并在iOS中从C引发这些事件.
I would like to register for events in Unity and raise those events from C in iOS.
我有以下模式-
// Unity side register delegate and event handler
private delegate void CallbackDelegate(CBObj data);
public static event CallbackDelegate dataUpdatedEvent;
// for iOS
#if !UNITY_EDITOR && UNITY_IOS
[DllImport("__Internal")]
private static extern void PluginFunction(CallbackDelegate callback);
#endif
public CBObj {
// marshal C objects to c# objects in the constructor here using the Ptr from C
}
[MonoPInvokeCallback(typeof(CallbackDelegate))]
static void CallbackMethod(CBObj dataPtr)
{
if (dataUpdatedEvent != null)
{
CBObj obj = new CBObj(dataPtr);
dataUpdatedEvent(obj);
}
}
// Unity Usage
private CallbackDelegate evt;
void Start(){
evt += updateEvent;
}
public void updateEvent(CBObj data){
// do something with data everytime its called
}
// C code
extern "C" typedef void (*CallBackFuncP) (CBObj dataPtr);
typedef struct
{
float *data1;
int *data2;
} CBObj;
extern "C" {
CallBackFuncP* cb;
void PluginFunction(CallBackFuncP callback) {
// store the the callback function pointer
cb = callback;
}
}
// raise the event somewhere in code
if (cb != NULL) {
CBObj *test = [[CBObj alloc] init];
cb(test)
}
这项工作吗?这是正确的模式吗?有更好的方法吗?
Would this work? Is this the correct pattern? Is there a better way to do it?
任何做到这一点的指针都受到高度赞赏.
Any pointers to do this are highly appreciated.
推荐答案
我通过以下模式解决了该问题,并且它运行正常.希望这对某人有帮助.
I solved it by the following patter and it worked flawlessly. Hope this helps someone.
// Unity side register delegate and event handler
delegate void Internal_CallbackDelegate(IntPtr dataPtr);
public delegate void CallbackDelegate(CBObj data);
// The above pattern is to deal with pointer conversion from iOS to Unity
public static event CallbackDelegate DataUpdatedEvent;
// YourUnityKlass for iOS
#if !UNITY_EDITOR && UNITY_IOS
[DllImport("__Internal")]
private static extern void PluginFunction(Internal_CallbackDelegate callback);
#endif
// Where this class is declared call in constructor
#if !UNITY_EDITOR && UNITY_IOS
PluginFunction(CallbackMethod);
#endif
public CBObj {
// marshal C objects to c# objects in the constructor here using the Ptr from C
private IntPtr m_Ptr;
internal CBObj(IntPtr ptr)
{
if (ptr == IntPtr.Zero)
throw new ArgumentException("ptr may not be IntPtr.Zero");
m_Ptr = ptr;
// getDataFromC();
}
// get individual pointers by exposing them via C and mashall copy the data as per your needs
}
[MonoPInvokeCallback(typeof(Internal_CallbackDelegate))]
static void CallbackMethod(IntPtr dataPtr)
{
if (DataUpdatedEvent != null)
{
CBObj obj = new CBObj(dataPtr);
DataUpdatedEvent(obj);
}
}
// Unity Usage
void Start(){
YourUnityKlass klass = new YourUnityKlass();
YourUnityKlass.DataUpdatedEvent += updateEvent;
}
public void updateEvent(CBObj data){
// do something with data every time its called
}
// C header - code
typedef struct
{
float *data1;
int *data2;
} CBObj;
typedef void (*CallBackFuncP) (CBObj* dataPtr);
@interface CallbackWrapper : NSObject
{
@public
CallBackFuncP _dataUpdate;
}
- (void) sendDataUpdate:(CBObj*) obj;
@end
// C - impl code
@implementation CallbackWrapper
-(void) sendDataUpdate:(CBObj*) objPtr
{
if (_dataUpdate != NULL){
_dataUpdate(objPtr);
}
}
@end
extern "C" {
void PluginFunction(CallBackFuncP callback) {
// Create a swiftKlass to store your callback pointer
CallbackWrapper* cb = [[SwiftKlass shared] getCallback];
cb->_dataUpdate = callback;
}
}
// Swift usage - Inside say SwiftKlass
@objc public func getCallback() -> CallbackWrapper {
return self.cb
}
这篇关于将事件从C提升到C#(iOS到Unity)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文