How do non-static callbacks work from native code?

♀尐吖头ヾ 提交于 2019-12-22 07:36:12

问题


It's a bit odd asking this question, because I have code that seems like it shouldn't work, but it does, and although I'm not complaining, I'd like to confirm why? LOL

Simply, I have a C++ native DLL (no CLR/managed support at all) that takes a call-back from C# code. The native side stores an stdcall callback function, which is supplied by the C# side. I always thought the callback METHOD (in C#) had to be static, but non-static and lambda expression BOTH work JUST FINE!? How is the "this" pointer being marshaled from native code? I always thought that native code only stores non-instance function pointers?

Now, I did find an article where some guy emitted IL code to "bridge" between native and non-static managed callbacks. I also noticed this depreciated method: "Marshal.GetUnmanagedThunkForManagedMethodPtr()". The method is no longer supported, which I'm assuming means it is built in?

Question summary:

  1. Is thunking now built natively into .NET by emitting IL code? If so, at what version of .NET did this become natively supported?

  2. Is implicit "thunking" supported in Mono as well?

  3. When the IL is emitted for the managed callbacks, what happens when the instance the thunk refers to is deleted? Is the IL removed, or might this lead to a memory "leak" so to speak?

Thanks.


回答1:


Is thunking now built natively into .NET by emitting IL code? If so, at what version of .NET did this become natively supported?

No IL in involved in the thunk, it happens by emitting native code -- a trampoline that rearranges arguments to meet .NET's calling convention, including the this pointer which is saved in case of closed delegates, and then performs a tail call to the .NET method itself.

Is implicit "thunking" supported in Mono as well?

This is called "reverse p/invoke", that should make it easy to look for in the Mono docs.

When the IL is emitted for the managed callbacks, what happens when the instance the thunk refers to is deleted?

When the delegate is garbage collected, memory used by the trampoline is also freed. So you need to keep the delegate alive as long as the native code has a pointer to the trampoline.




回答2:


The interop marshaller simply marshals a delegate. The delegate can be either an class delegate (no this) or an instance delegate (has a this). From the standpoint of C#, it's just calling a delegate. i.e. the same semantics used to manage this with an instance delegate (e.g. the decoupling of the class instance) is effectively used.

Clearly there's more going on under the covers with other things (like pinning, etc.)--but they're generally unrelated to what you've asked.



来源:https://stackoverflow.com/questions/15666173/how-do-non-static-callbacks-work-from-native-code

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!