.net 在 C++/CLI 中,如何声明和调用带有“out”参数的函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/186477/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 10:17:15  来源:igfitidea点击:

In C++/CLI, how do I declare and call a function with an 'out' parameter?

.netc++-clipass-by-reference

提问by Simon

I have a function which parses one string into two strings. In C# I would declare it like this:

我有一个将一个字符串解析为两个字符串的函数。在 C# 中,我会像这样声明它:

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

and I'd call it like this:

我会这样称呼它:

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

The current project has to be done in C++/CLI. I've tried

当前项目必须在 C++/CLI 中完成。我试过了

using System::Runtime::InteropServices;

...

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

but if I call it like this:

但如果我这样称呼它:

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

I get a compiler error, and if I call it like this:

我收到一个编译器错误,如果我这样称呼它:

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

then I get an error at runtime. How should I declare and call my function?

然后我在运行时收到错误。我应该如何声明和调用我的函数?

回答by Bert Huijben

C++/CLI itself doesn't support a real 'out' argument, but you can mark a reference as an out argument to make other languages see it as a real out argument.

C++/CLI 本身不支持真正的“out”参数,但您可以将引用标记为 out 参数,以使其他语言将其视为真正的 out 参数。

You can do this for reference types as:

您可以对引用类型执行此操作:

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

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

And for value types as:

对于值类型为:

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

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

The % makes it a 'ref' parameter and the OutAttribute marks that it is only used for output values.

% 使其成为“ref”参数,而 OutAttribute 标记它仅用于输出值。

回答by Simon

Using Visual Studio 2008, this works and solved a major problem at my job. Thanks!

使用 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);
        }
     }
}

回答by Greg Dean

It's not supported. The closest you can get is ref

不支持。你能得到的最接近的是 ref

Granted you can fake it, but you lose a compile time check.

当然,您可以伪造它,但是您会丢失编译时检查。