.net - Cómo arreglar CA2123(las demandas de reemplazo de enlace deben ser idénticas a la base) en un proyecto administrado de C++/CLI
.net-4.0 c++-cli (1)
No puedo entender cómo corregir CA2123 para un proyecto de C ++ / CLI. Aquí hay un proyecto de muestra para demostrar el problema:
1) Crear una biblioteca de clases de C # (.NET 4)
ManagedClass.cs
espacio de nombre CSharpLibrary {
public interface IManagedClass
{
void WriteSomething();
}
public class ManagedClass : IManagedClass
{
public void WriteSomething()
{
}
}
}
2) Crear una aplicación de consola C ++ / CLI (VS 2010):
AssemblyInfo.cpp
#include "stdafx.h"
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security;
[assembly:AssemblyTitleAttribute("CPlusPlusCLIConsoleApp")];
[assembly:AssemblyDescriptionAttribute("")];
[assembly:AssemblyVersionAttribute("1.0.*")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(false)];
[assembly:SecurityCritical];
CPlusPlusCLIConsoleApp.h
#pragma once
using namespace CSharpLibrary;
using namespace System::Security;
typedef void* (__cdecl FACTORY_PROC)();
namespace CPlusPlusCLIConsoleApp
{
public ref class MainClass : public IManagedClass
{
public:
[SecurityCritical]
virtual void WriteSomething();
};
};
CPlusPlusCLIConsoleApp.cpp
#include "stdafx.h"
#include "CPlusPlusCLIConsoleApp.h"
using namespace System;
int main(){};
namespace CPlusPlusCLIConsoleApp
{
[SecurityCritical]
void MainClass::WriteSomething()
{
}
};
Después de habilitar todas las Reglas de seguridad de Microsoft, recibo esta advertencia:
CA2123 Las demandas de enlace de anulación deberían ser idénticas a la base
Agregue el siguiente atributo de seguridad a ''MainClass :: WriteSomething (void)'' para que coincida con un LinkDemand en el método base ''IManagedClass :: WriteSomething (void)'': ''SecurityCriticalAttribute''.
CPlusPlusCLIConsoleApp cpluspluscliconsoleapp.cpp 13
Traté de seguir lo que sugirió esta respuesta de StackOverflow, pero no solucionó el error.
Entiendo que el dll administrado es por defecto SecurityCritical (no quiero cambiar esto en mi proyecto original) ya que no especifico ningún SecurityAttribute. ¿Por qué la DLL de C ++ no sigue el mismo valor predeterminado?
¿Qué pasos debo seguir para solucionar este error? (Básicamente, ¿cómo puedo hacer WriteSomething método SecurityCritical en C ++ CLI)
EDIT 1: He hecho la misma pregunta en MSDN .
EDIT 2: contactó a Microsoft y es un comportamiento diseñado. El equipo de C ++ / CLI simplemente no tuvo tiempo para implementar Level2 Security para C ++ / CLI. Por lo tanto C ++ / CLI siempre está bloqueado en Level1 Security. Uno puede suprimir de forma segura la advertencia de análisis de código para el mismo.
El problema de raíz aquí es que los ensamblajes C # y C ++ utilizan dos modelos de transparencia diferentes (consulte http://blogs.msdn.com/b/shawnfa/archive/2009/11/11/transparency-models-a-tale-of -two-levels.aspx y http://blogs.msdn.com/b/shawnfa/archive/2009/11/12/differences-between-the-security-rule-sets.aspx para obtener detalles de los dos niveles). Esto se debe a que el ensamblado C # compila al nivel 2 de forma predeterminada, pero el ensamblador C ++ se ve forzado automáticamente al nivel 1 por el compilador por algún motivo aparentemente no documentado. Desafortunadamente, parece que este último comportamiento no es invaluable. Para empeorar las cosas, no parece haber cambiado en VS2012, y no parece que el equipo del producto esté considerando cambiarlo pronto .
Dado que no puede mover el conjunto de C ++ al nivel 2, tiene un par de opciones potencialmente viables si desea mantener el ejecutable en C ++ y debe contener la implementación de la interfaz:
- Mueva el conjunto C # al nivel 1 mediante el uso de SecurityRulesAttribute. Supuestamente, esto solo sería aceptable si la aplicación de consola C ++ es el único consumidor de la biblioteca C #.
Reproduzca la "intensificación" del nivel 2 de la criticidad de la seguridad a una demanda de enlace / herencia de confianza completa mediante el uso de PermissionSetAttribute. p.ej:
[SecurityCritical] [PermissionSet(SecurityAction::LinkDemand, Unrestricted = true)] [PermissionSet(SecurityAction::InheritanceDemand, Unrestricted = true)] virtual void WriteSomething();
También podría valer la pena presentar otro informe de errores en Connect (votar por los cerrados no parece ser muy útil) o una solicitud de función en UserVoice para solicitar que se modifique el comportamiento del compilador. (Bloquear en el nivel 1 es bastante extraño dado que se supone que el nivel 2 es el predeterminado para .NET 4.0 y superior).