概要
関数ポインタを比較しようとすると警告が生成される。
CS8909: 同じ関数へのポインターがそれぞれ異なっている可能性があるため、関数ポインターの比較によって予期しない結果が生成される恐れがあります。
Taking address of the same method twice is not guaranteed to produce same pointer.
(https://github.com/dotnet/roslyn/issues/48919#issuecomment-717391699)
なぜだかは不明だが同一の関数を指すポインタは複数あるらしい。
アドレスが飛んでしまうことのパフォーマンスへの悪影響によるものかもしれないが、不詳。
対処法
とりあえずそういう性質があるという事実を受け止めて、なんとか対処しよう。
複数回取得した場合のポインタが同一であることが保証されないのだから、一回取得してそれを使い回せばいいだろう。
static Dictionary<MethodInfo, nint> _cache = new();
public static nint GetAddress(MethodInfo mI)
{
if (!_cache.TryGetValue(mI, out var v))
_cache.Add(mI, v = mI.MethodHandle.GetFunctionPointer());
return v;
}
どのような経緯で関数ポインタの値が異なるのかわからない以上、一度異なってしまったアドレスが同一の関数を指すのかどうかを調べるのは困難である。
リフレクション経由になるのでパフォーマンス面で劣るが、良い解決策は講じれなかった。
最後に
なぜ同一の関数に対するポインターが異なってしまうのかについて情報を持っている方がいたら教えていただきたい。
参考