2014-11-18 16 views
16

Ho provato VS2015 con la mia soluzione esistente e ho ricevuto alcuni nuovi errori validi (come il codice irraggiungibile che il compilatore non ha catturato prima), ma ho anche un errore per esempio su questa linea :C# 6/C++ ref Parola chiave errore

bool bWasAlreadyLocked = false; 
oEnv.LockDoc(oWarnings, oEventDoc, ref bWasAlreadyLocked); 

ottengo il seguente errore:

Error CS1503 Argument 3: cannot convert from 'ref bool [mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]' to 'ref bool [mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]'

non riesco a capire perché getterebbe tale errore, ovviamente, i tipi corrispondono. Si tratta di un bug nel nuovo compilatore o il comportamento della parola chiave ref è cambiato?

La funzione in questo caso è una funzione C++ che viene importata in C# utilizzando una classe C# derivata dalla classe C++. E 'firma è questa:

void CBkgDocEnvX::LockDoc(
CFIWarningList ^oWarnings, 
CBaseDoc ^oBaseDoc, 
// Output 
bool %rbWasAlreadyLocked) 

Potrebbe essere buono di dire che ho optato per utilizzare il compilatore VS2013 C++ per il C++ fonti nella soluzione, per ora, in modo che il C++ lato dovrebbe essere la stessa di prima. La mia ipotesi è che qualcosa nell'interp tra C# e C++ sia cambiato.

+1

Qual è la firma di 'LockDoc'? –

+0

Cercalo, è una funzione C++ –

+0

E '%' sembra essere un operatore di localizzazione C++. Non sei sicuro di come gestirlo in C#. –

risposta

0

Si scopre che questo errore può essere risolto aggiungendo esplicitamente un attributo out al parametro.

L'aggiunta di [Out] al parametro ref sembra aiutare il nuovo compilatore C# a riconoscere che si tratta degli stessi tipi e di accettarli. I metodi nella nostra soluzione di interoperabilità ora sono:

using namespace System::Runtime::InteropServices; 

... 

virtual void LockDoc(
    CFIWarningList ^oWarnings, 
    CBaseDoc ^oBaseDoc, 
// Output 
    [Out] bool %rbWasAlreadyLocked 
    ) override; 
1

Controllare questo punto per sicurezza.

  1. Solo i valori L possono essere passati per riferimento. Il valore L è costituito da variabili e altre espressioni che possono essere visualizzate nella parte sinistra di un compito. Questi includono l'inclusione di locals, accessi al campo, dereferenze del puntatore e accessi agli elementi dell'array. I valori L non includono gli accessi alle proprietà, che non hanno un indirizzo macchina identificabile, né includono campi di sola lettura, che sono limitati dal CLR.
  2. I parametri di riferimento non possono essere il target di un metodo di estensione. Le chiamate dei metodi di estensione sono costose per i tipi di valore, poiché il parametro "questo" viene copiato in base al valore. Ciò significa anche che i tipi di valore non possono avere metodi di estensione mutabili. Ciò è in diretto contrasto con i metodi di istanza, che passano il parametro di tipo "questo" per riferimento.
  3. I parametri di riferimento non possono essere utilizzati nelle funzioni di sovraccarico dell'operatore.

Potete trovare ulteriori informazioni here.

+0

Tutto sembra sensato, ma non nuovo. Poiché il codice funziona in VS2013, dubito che sia causato da uno di questi casi, ma correggimi se sbaglio. Inoltre, puoi vedere la dichiarazione dei parametri ref sopra. –

0

Si potrebbe provare a utilizzare un tipo di dati Oggetto anziché Booleano. Successivamente è possibile analizzarlo su Boolean.

+1

Oppure non è possibile utilizzare VS2015 mentre questo non funziona, invece di rimuovere la digitazione in centinaia di punti del progetto;) –

1

Ottengo quei tipi di errori del compilatore quando due progetti sono di tipi incompatibili. Spesso Visual Studio mi consente di aggiungere un riferimento a un progetto Libreria di classi portatile (o progetto .NET 4.0) anche quando l'assembly a cui si fa riferimento non è supportato dal tipo di profilo .NET del progetto di riferimento.

L'evento più comune per me è quando si utilizza un progetto .NET 4.0 e si tenta di fare riferimento a un probabile progetto Libreria di classi che specifica .NET 4.5 nelle impostazioni del profilo anziché nella precedente versione .NET 4. Quando faccio riferimento all'assembly PCL dal mio progetto .NET 4.0, continuo ad ottenere il pieno supporto intellisense (ad esempio quando si modifica il codice sorgente intellisense visualizzerà tutti i namespace, le classi e le proprietà contenute all'interno dell'assembly a cui si fa riferimento) Ma al momento della compilazione ottengo il lo stesso tipo di errore che stai ricevendo; più specificamente quando compilo la soluzione, la compilazione indica una discrepanza di libreria, ma elenca esattamente la stessa libreria, versione e chiave pubblica che dice che sta cercando.

Controllare le proprietà del progetto, verificare che siano compatibili.