2014-11-18 7 views
16

Ich versuchte VS2015 mit meiner bestehenden Lösung und ich bekomme einige gültige neue Fehler (wie unerreichbarer Code, den der Compiler nicht zuvor gefangen hat), aber ich bekomme auch einen Fehler zum Beispiel in dieser Zeile :C# 6/C++ ref Schlüsselwort Fehler

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

bekomme ich folgende Fehlermeldung:

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]'

ich kann nicht sehen, warum es diesen Fehler werfen würde, offensichtlich die Typen passen. Ist das ein Fehler im neuen Compiler oder hat sich das Verhalten des Schlüsselworts ref geändert?

Die Funktion in diesem Fall ist eine C++ - Funktion, die mit einer C# -Klasse aus der C++ - Klasse in C# importiert wird. Es ist Unterschrift ist dies:

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

Es könnte gut sein, zu erwähnen, dass ich den VS2013 C++ Compiler für die C++ Quellen in der Lösung für die jetzt zu verwenden, entschieden, so die C++ Seite sollte das gleiche sein wie zuvor. Meine Vermutung ist, dass sich etwas im Interop zwischen C# und C++ geändert hat.

+1

Was ist die Signatur von 'LockDoc'? –

+0

Sah es auf, es ist eine C++ Funktion –

+0

Und '%' scheint ein C++ Tracking-Operator zu sein. Ich bin mir nicht sicher, wie ich in C# damit umgehen soll. –

Antwort

0

Es stellt sich heraus, dass dieser Fehler durch explizites Hinzufügen eines aus Attribute auf den Parameter festgelegt werden kann.

Das Hinzufügen von [Out] zu dem ref Parameter hilft dem neuen C# -Compiler offensichtlich zu erkennen, dass es sich um dieselben Typen handelt, und akzeptiert sie. Die Methoden in unserer Interop-Lösung sehen nun wie folgt aus:

using namespace System::Runtime::InteropServices; 

... 

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

Sie sollten diesen Punkt nur zur Sicherheit überprüfen.

  1. Nur L-Werte können durch einen Verweis übergeben werden. L-Wert sind Variablen und andere Ausdrücke, die auf der linken Seite einer Zuweisung erscheinen können. Dazu gehören lokale, Feldzugriffe, Zeigerdereferenzen und Arrayelementzugriffe. L-Werte umfassen keine Eigenschaftenzugriffe, die keine identifizierbare Maschinenadresse aufweisen, noch enthalten sie schreibgeschützte Felder, die durch die CLR beschränkt sind.
  2. Ref-Parameter können nicht das Ziel einer Erweiterungsmethode sein. Aufrufe von Erweiterungsmethoden sind für Werttypen teuer, da der Parameter "this" nach Wert kopiert wird. Dies bedeutet auch, dass Werttypen keine änderbaren Erweiterungsmethoden haben können. Dies steht in direktem Gegensatz zu Instanzmethoden, die den Werttyp "this" -Parameter als Referenz übergeben.
  3. Ref-Parameter können nicht in Überlastungsfunktionen des Operators verwendet werden.

Sie finden weitere Informationen here.

+0

Das klingt alles vernünftig, aber nicht neu. Wie der Code in VS2013 funktioniert, bezweifle ich, dass es durch einen dieser Fälle verursacht wird, aber korrigieren Sie mich, wenn ich falsch liege. Außerdem können Sie die obige Ref-Parameter-Deklaration sehen. –

0

Sie könnten versuchen, einen Objektdatentyp anstelle von Boolean zu verwenden. Danach können Sie es auf Boolean analysieren.

+1

Oder ich konnte VS2015 nicht verwenden, während dies nicht funktioniert, anstatt die Eingabe an hunderten von Stellen im gesamten Projekt zu entfernen;) –

1

Ich erhalte diese Arten von Compiler-Fehlern, wenn zwei Projekte von inkompatiblen Typen sind. In Visual Studio kann ich häufig einen Verweis auf ein Portable Class Library-Projekt (oder .NET 4.0-Projekt) hinzufügen, auch wenn die referenzierte Assembly vom .NET-Profiltyp des referenzierenden Projekts nicht unterstützt wird.

Das häufigste Vorkommen für mich ist, wenn Sie ein .NET 4.0-Projekt verwenden und versuchen, ein Probable Class Library-Projekt zu referenzieren, das .NET 4.5 in seinen Profileinstellungen statt der älteren .NET 4-Version angibt. Wenn ich die PCL-Assembly von meinem .NET 4.0-Projekt referenziere, bekomme ich weiterhin volle Intellisense-Unterstützung (zB wenn ich den Quellcode editiere, werden alle Namespaces, Klassen und Eigenschaften innerhalb der Assembly angezeigt, auf die verwiesen wird) die gleiche Art von Fehler, den du bekommst; Genauer gesagt, wenn ich die Lösung kompiliere, weist die Kompilierung auf eine nicht übereinstimmende Bibliothek hin, listet aber genau die Bibliothek, die Version und den öffentlichen Schlüssel auf, die sie suchen.

Überprüfen Sie die Projekteigenschaften und vergewissern Sie sich, dass sie kompatibel sind.