C#9 introdujo punteros a funciones no administradas (p. ej delegate* unmanaged[Cdecl]<void> ). He estado experimentando con estos para aprender cómo funcionan. Después de actualizar a .NET 5.0.201, recibí una nueva advertencia:
error CS8909: Comparison of function pointers might yield an unexpected result, since pointers to the same function may be distinct.De acuerdo con este problema , es posible que tomar la referencia de una función administrada más de una vez no siempre produzca el mismo puntero.
Este es un ejemplo del tipo de código que podría activar esta advertencia:
// saves a function pointer in unmanaged code [DllImport("mylib", CallingConvention = CallingConvention.Cdecl)] static extern void set_func(delegate* unmanaged[Cdecl]<void> func); // retrieves the function pointer that was saved above [DllImport("mylib", CallingConvention = CallingConvention.Cdecl)] static extern delegate* unmanaged[Cdecl]<void> get_func(); // unmanaged function implemented in C# [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })] static void MyFunc() { ... } void Test() { // pass our unmanaged callers only function to unmanaged code set_func(&MyFunc); ... // sometime later we want to check if unmanaged code still has the same function // pointer or if it changed if (get_func() == (delegate* unmanaged[Cdecl]<void>)&MyFunc) { // this line triggers CS8909 warning ... } } Puedo ver cómo el código no funcionaría correctamente si la primera llamada a &MyFunc un puntero de función diferente al de la segunda llamada a &MyFunc . Así que la advertencia tiene sentido.
¿Qué alternativa podría usarse para realizar el mismo tipo de prueba que no genera el problema indicado por la advertencia CS8909?
Por ejemplo, ¿es esto seguro?
// identical code from above is omitted for brevity, only Test() method is changed static readonly delegate* unmanaged[Cdecl]<void> myFunc = &MyFunc; void Test() { // pass our unmanaged callers only function to unmanaged code set_func(myFunc); ... // sometime later we want to check if unmanaged code still has the same function // pointer or if it changed #pragma warning disable CS8909 if (get_func() == myFunc) { // would still trigger warning CS8909 if it was enabled #pragma warning restore CS8909 ... }¿Existe otra alternativa que pueda evitar tener que desactivar el aviso?