Как в C ++ / CLI объявить и вызвать функцию с параметром out? - PullRequest
46 голосов
/ 09 октября 2008

У меня есть функция, которая разбирает одну строку на две строки. В C # я бы объявил это так:

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

и я бы назвал это так:

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

Текущий проект должен быть выполнен в C ++ / CLI. Я пробовал

using System::Runtime::InteropServices;

...

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

но если я назову это так:

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

Я получаю ошибку компилятора, и если я назову ее так:

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

тогда я получаю ошибку во время выполнения. Как мне объявить и вызвать мою функцию?

Ответы [ 3 ]

78 голосов
/ 09 октября 2008

C ++ / CLI сам по себе не поддерживает реальный аргумент 'out', но вы можете пометить ссылку как аргумент out, чтобы другие языки воспринимали ее как реальный аргумент out.

Вы можете сделать это для справочных типов как:

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

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

И для типов значений как:

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

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

% делает его параметром 'ref', а OutAttribute отмечает, что он используется только для выходных значений.

10 голосов
/ 26 мая 2010

Используя Visual Studio 2008, это работает и решило серьезную проблему на моей работе. Спасибо!

// 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);
        }
     }
}
0 голосов
/ 09 октября 2008

Это не поддерживается. Самое близкое, что вы можете получить, это ref

Конечно, вы можете подделать его, но вы потеряете проверку времени компиляции.

...