2008-10-09 7 views
43

Ich habe eine Funktion, die eine Zeichenfolge in zwei Zeichenfolgen analysiert. In C# würde ich es wie folgt erklären:In C++/CLI, wie deklariere ich und rufe eine Funktion mit einem 'out' Parameter auf?

void ParseQuery(string toParse, out string search, out string sort) 
{ 
    ... 
} 

und ich es so nennen würde:

string searchOutput, sortOutput; 
ParseQuery(userInput, out searchOutput, out sortOutput); 

Das aktuelle Projekt hat in C++/CLI zu tun. Ich habe versucht,

using System::Runtime::InteropServices; 

... 

void ParseQuery(String^toParse, [Out] String^ search, [Out] String^ sort) 
{ 
    ... 
} 

aber wenn ich nenne es wie folgt aus:

String^searchOutput,^sortOutput; 
ParseQuery(userInput, [Out] searchOutput, [Out] sortOutput); 

ich einen Compiler-Fehler, und wenn ich es so nennen:

String^searchOutput,^sortOutput; 
ParseQuery(userInput, searchOutput, sortOutput); 

dann bekomme ich ein Fehler zur Laufzeit. Wie soll ich meine Funktion deklarieren und aufrufen?

+0

Ich denke, dass sollte 'Namespace verwenden System :: Runtime :: InteropServices;' anstelle von 'mit System :: Runtime :: InteropServices;'. – teeks99

Antwort

67

C++/CLI selbst unterstützt kein echtes "out" -Argument, aber Sie können eine Referenz als out-Argument markieren, damit andere Sprachen es als reales Argument betrachten.

Sie können diese Arten als Referenz tun wie:

void ReturnString([Out] String^% value) 
{ 
    value = "Returned via out parameter"; 
} 

// Called as 
String^ result; 
ReturnString(result); 

Und für Werttypen wie:

void ReturnInt([Out] int% value) 
{ 
    value = 32; 
} 

// Called as 
int result; 
ReturnInt(result); 

Die% macht es ein ‚ref‘ Parameter und die OutAttribute markiert, dass es nur Wird für Ausgabewerte verwendet.

+1

Ich glaube nicht, dass dies derselbe wie der C# out Modifier ist. Zum Beispiel in C#, wenn ein Parameter markiert und nicht zugeordnet ist, führt dies zu einem Compilerfehler. Ist das in Ihrem Beispiel dasselbe? –

+1

So werden C# out-Parameter auf der IL-Ebene implementiert: Es gibt nur eine ref-Aufrufkonvention, die für ref und out in C# verwendet wird. Die Annotation mit einem OutAttribute macht es zu einem out-Parameter. –

+0

Siehe auch: http://msdn.microsoft.com/en-us/magazine/cc164193.aspx#S2 –

0

Es wird nicht unterstützt. Die nächste, die Sie bekommen können, ist Ref

Zugegeben, Sie können es fälschen, aber Sie verlieren eine Kompilierzeit überprüfen.

+0

OK ... Wie würde ich eine Funktion mit ref-Parametern in verwaltetem C++ deklarieren und aufrufen? – Simon

+1

Nicht sicher, warum dies abgelehnt wurde. Wenn es tatsächlich nicht unterstützt wird. Zugegeben, Sie können es fälschen, aber Sie verlieren eine Kompilierzeitprüfung. Das ist eine ziemlich große Sache. Imo –

+0

C++/CLI kann C# 'out' Parameter aufrufen, die sie wie' ref' Parameter behandeln. Der Unterschied scheint nur auf der aufrufenden Seite zu liegen (Die C++ - Definition ist dieselbe wie die C# -Definition, die immer noch 'out' spezifiziert und beide C# -Rufe begrenzen sollten) –

8

Mit Visual Studio 2008 funktioniert dies und löste ein großes Problem bei meiner Arbeit. Vielen Dank!

// header 
// Use namespace for Out-attribute. 
using namespace System::Runtime::InteropServices; 
namespace VHT_QMCLInterface { 
    public ref class Client 
    { 
    public: 
     Client(); 
     void ReturnInteger(int a, int b, [Out]int %c); 
     void ReturnString(int a, int b, [Out]String^ %c); 
    } 
} 

// cpp 
namespace VHT_QMCLInterface { 

    Client::Client() 
    { 

    } 

    void Client::ReturnInteger(int a, int b, [Out]int %c) 
    { 
     c = a + b; 
    } 
    void Client::ReturnString(int a, int b, [Out]String^ %c) 
    { 
     c = String::Format("{0}", a + b); 
    } 
} 

// cs 
namespace TestQMCLInterface 
{ 
    class Program 
    { 
     VHT_QMCLInterface.Client m_Client = new VHT_QMCLInterface.Client(); 
     static void Main(string[] args) 
     { 
      Program l_Program = new Program(); 
      l_Program.DoReturnInt(); 
      l_Program.DoReturnString(); 
      Console.ReadKey(); 
     } 

     void DoReturnInt() 
     { 
      int x = 10; 
      int y = 20; 
      int z = 0; 
      m_Client.ReturnInteger(x, y, out z); 
      Console.WriteLine("\nReturnInteger: {0} + {1} = {2}", x, y, z); 
     } 

     void DoReturnString() 
     { 
      int x = 10; 
      int y = 20; 
      String z = "xxxx"; 
      m_Client.ReturnString(x, y, out z); 
      Console.WriteLine("\nReturnString: {0} + {1} = '{2}'", x, y, z); 
     } 
    } 
} 
Verwandte Themen