坑二:Delegate的正确使用姿势
时间:2022-04-28 21:33:01 | 来源:行业动态
时间:2022-04-28 21:33:01 来源:行业动态
如果Managed侧的编程语言是C#,则Delegate是实现回调的重要手段。在Unmanaged侧完成期望工作时回调一个FunctionPtr即可实现通用的回调模式,而此FunctionPtr正是对应到Managed侧的Delegate。当你的Delegate绑定到一个类对象上时,你有两种选择:
namespaceChatSDK{//delegatedefinitionpublicvoiddelegateOnMessageReceived(EMMessagemessage);publicclassMyDelegate{//Option1:fieldpublicOnMessageReceivedMyMessageReceived;//Option2:instancemethodpublicvoidOnMessageReceived(EMMessagemessage){...}}//senddelegatemethodtounmanagedsideMyDelegatemd=new();NativeMethods.SetOnMessageReceivedCallback(md.MyMessageReceived);//option1NativeMethods.SetOnMessageReceivedCallback(md.OnMessageReceived);//option2}
看起来两个方式都没有问题,并且第二个方式看起来更顺眼。但是这里隐藏着一个很深的坑,就是你选择第二个方式的时候,如果你在回调方法实现中采用this.xxx方式引用时,你会发现this = null!这是因为当你使用这种方式传递一个对象的方法作为回调方法指针时,其实已经丢失了Delegate.Target(也就是this)属性。而通过第一种方式传递的是一个对象的属性/字段,它和对象本身的绑定是不会在传递过程中丢失的。
至于该Delegate字段的定义可以在此类的构造函数中通过以下方式实现:
...publicMyDelegate(){MyMessageReceived=(EMMessagemessage)={...}}...