2013-07-10 9 views
8

Non riesco a capire come risolvere CA2123 per un progetto C++/CLI. Ecco un progetto di esempio per dimostrare il problema:Come risolvere CA2123 (le richieste di collegamento Override devono essere identiche alla base) in un progetto C++/CLI gestito

1) Creare un C# (.NET 4) Libreria di classi

ManagedClass.cs

namespace CSharpLibrary {

public interface IManagedClass 
{ 
    void WriteSomething(); 
} 

public class ManagedClass : IManagedClass 
{ 
    public void WriteSomething() 
    { 
    } 
} 

}

2) Creare un'app Console 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() 
    { 
    } 
}; 

Dopo enab ling tutte le regole di sicurezza di Microsoft, ottengo questo avvertimento:

richieste di collegamento CA2123 Override devono essere identici basare

Aggiungere il seguente attributo di sicurezza per 'MainClass :: writeSomething (void)' al fine di corrispondere a LinkDemand su metodo di base 'IManagedClass :: WriteSomething (void)': 'SecurityCriticalAttribute'.

CPlusPlusCLIConsoleApp cpluspluscliconsoleapp.cpp 13

ho cercato di seguire ciò che questo StackOverflow answer suggerito, ma non risolvere l'errore.

Capisco che la DLL gestita è di default SecurityCritical (non voglio cambiarlo nel mio progetto originale) poiché non specifica alcun SecurityAttribute. Perché la dll CLI C++ non segue la stessa impostazione predefinita?

Quali passi devo seguire per risolvere questo errore? (In fondo come posso fare metodo writeSomething SecurityCritical in C++ CLI)

EDIT 1: ho chiesto la stessa domanda su MSDN.

EDIT 2: Contattato Microsoft ed è un comportamento come progettato. Il team C++ \ CLI non ha avuto il tempo di implementare Level2 Security per C++ \ CLI. Quindi C++ \ CLI è sempre bloccato a livello 1 di sicurezza. Si può tranquillamente sopprimere l'avviso di analisi del codice per lo stesso.

+0

"Ho cercato di seguire ciò che questa risposta StackOverflow ha suggerito ma non ha corretto l'errore." - ma il codice che hai postato non riflette questo: hai aggiunto [assembly: SecurityCritical] a AssemblyInfo.cpp? –

+0

È troppo semplice ignorare la richiesta, il chiamante può semplicemente trasmettere il riferimento all'oggetto al tipo di interfaccia ed effettuare la chiamata. L'attributo pertanto deve essere applicato anche al metodo dell'interfaccia. –

+0

@SebastianRedl Sì. Ho appena dimenticato di copiare l'attributo qui. Aggiustato. –

risposta

9

Il problema principale qui è che gli assembly C# e C++ utilizzano due diversi modelli di trasparenza (vedere http://blogs.msdn.com/b/shawnfa/archive/2009/11/11/transparency-models-a-tale-of-two-levels.aspx e http://blogs.msdn.com/b/shawnfa/archive/2009/11/12/differences-between-the-security-rule-sets.aspx per i dettagli dei due livelli). Questo perché l'assembly C# viene compilato al livello 2 per impostazione predefinita, ma l'assembly C++ viene automaticamente forzato al livello 1 dal compilatore per motivi apparentemente non documentati. Sfortunatamente, sembra che quest'ultimo comportamento non sia superabile. A peggiorare le cose, non sembra essere cambiato in VS2012 e it doesn't look like the product team is considering changing it any time soon.

Dato che non è possibile spostare il gruppo C++ al livello 2, si dispone di un paio di scelte potenzialmente vitali se si desidera mantenere il file eseguibile in C++ e deve contenere l'implementazione dell'interfaccia:

  1. Sposta l'assembly C# al livello 1 tramite l'uso di SecurityRulesAttribute. Questo presumibilmente sarebbe accettabile solo se l'app della console C++ è l'unico consumatore della libreria C#.
  2. Riprodurre il livello 2 "escalation" di criticità di sicurezza su un totale di di trust link o richiesta di ereditarietà tramite l'uso di PermissionSetAttribute. esempio:

    [SecurityCritical] 
    [PermissionSet(SecurityAction::LinkDemand, Unrestricted = true)] 
    [PermissionSet(SecurityAction::InheritanceDemand, Unrestricted = true)] 
    virtual void WriteSomething(); 
    

Potrebbe anche essere utile per inviare un'altra segnalazione di bug su Connect (votando per quelle chiuse non sembra essere molto utile), o una richiesta di funzionalità su UserVoice per richiedere che il compilatore comportamento essere cambiato. (Il blocco al livello 1 è piuttosto dannoso dato che il livello 2 dovrebbe essere il predefinito per .NET 4.0 e versioni successive.)

+0

+1 Grazie per la risposta. Ottimi collegamenti. Penso che quello che stai dicendo sia la risposta. Aspetta solo il supporto Microsoft per confermare questo. –