通过反射订阅第三方SDK事件时值类型参数损坏问题排查
解决方案
这个问题和数据封送、反射绑定特性无关,本质是值类型装箱与委托签名不匹配导致的参数损坏。
问题根源
事件的委托签名是Action<string, AdSdkBase.Reward, AdSdkBase.AdInfo>,其中Reward是值类型。你订阅的方法用object接收Reward,事件触发时Reward会被装箱为object,但反射创建委托时,签名不匹配会导致值类型的内存布局被错误解析,最终只有部分字段能正常读取。
修复方案
方案1:让方法签名与委托完全匹配
直接使用SDK定义的具体类型作为方法参数,不要用object接收:
public void OnAdReceivedReward(string adUnitId, AdSdkBase.Reward reward, AdSdkBase.AdInfo adInfo) { Debug.Log($"id: {adUnitId}"); Debug.Log($"reward: {reward}"); // 此时Label和Amount都能正常获取 Debug.Log($"info: {adInfo}"); }
这样Delegate.CreateDelegate能正确绑定委托,值类型传递不会出现损坏。
方案2:反射读取字段(无法直接引用SDK类型时)
如果因为程序集引用限制,不能直接使用AdSdkBase.Reward,可以在回调中通过反射读取字段值:
public void OnAdReceivedReward(string adUnitId, object reward, object adInfo) { Debug.Log($"id: {adUnitId}"); // 反射获取结构体的字段值 var rewardType = reward.GetType(); var label = rewardType.GetField("Label").GetValue(reward); var amount = rewardType.GetField("Amount").GetValue(reward); Debug.Log($"reward: Label={label}, Amount={amount}"); Debug.Log($"info: {adInfo}"); }
这种方式绕开了装箱后的类型匹配问题,直接读取内存中的字段值,能避免参数损坏。
内容的提问来源于stack exchange,提问作者earthQuake
相关产品推荐
相关产品推荐

