将 List<String^> 从 C++ 传递到 C#

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17046193/
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-08-10 08:26:57  来源:igfitidea点击:

Passing a List<String^> from c++ to C#

c#c++-cli

提问by Jan

Not that experienced with c++, so requesting some help here. What I got is a .net dll and I'm writing a wrapper, so that the .net dll can be used later in c++ and vb6 projects.

对 C++ 没有经验,所以在这里请求一些帮助。我得到的是一个 .net dll,我正在编写一个包装器,以便稍后可以在 c++ 和 vb6 项目中使用 .net dll。

My code so far:

到目前为止我的代码:

c# class I want to call:

我想调用的 c# 类:

public class App
{
   public App(int programKey, List<string> filePaths)
   {
       //Do something
   }
}

my c++ project:

我的 C++ 项目:

static int m_programKey;
static vector<std::string> m_fileNames;

void __stdcall TicketReportAPI::TrStart(int iProgramKey)
{
    m_programKey = iProgramKey;
};

void __stdcall TicketReportAPI::TrAddFile(const char* cFileName)
{
    string filename(cFileName);
    m_fileNames.push_back(filename);
}


void __stdcall TicketReportAPI::TrOpenDialog()
{

    if(m_fileNames.size()> 0)
    {

        List<String^> list = gcnew List<String^>();

        for(int index = 0; index < m_fileNames.size(); index++)
        {

            std::string Model(m_fileNames[index]);
            String^ sharpString = gcnew String(Model.c_str());

            list.Add(gcnew String(sharpString));
        }


        App^ app = gcnew App(m_programKey, list);

    }
    else
        App^ app = gcnew App(m_programKey);

}

If I'm trying to compile the c++ project I get following error:

如果我试图编译 C++ 项目,我会收到以下错误:

App(int,System::Collections::Generic::List ^)': Conversion from 'System::Collections::Generic::List' to 'System::Collections::Generic::List ^' not possible

App(int,System::Collections::Generic::List ^)':从 'System::Collections::Generic::List' 到 'System::Collections::Generic::List ^' 的转换是不可能的

Is it possible to pass a managed List from c++ to .net c#? If not, what do you guys suggest me to pass a string array to my c# assembly?

是否可以将托管列表从 c++ 传递到 .net c#?如果没有,你们有什么建议我将字符串数组传递给我的 C# 程序集?

Every help is appreciated, Thanks in advance.

感谢每一个帮助,提前致谢。

采纳答案by David Yaw

You're missing a ^.

你缺少一个^.

List<String^>^ list = gcnew List<String^>();
             ^-- right here

You'll also need to switch list.Addto list->Add.

您还需要切换list.Addlist->Add.

You're using gcnew, which is how you create something on the managed heap, and the resulting type is a managed handle, ^. This is roughly equivalent to using newto create an object on the unmanaged heap, and the resulting type is a pointer, *.

您正在使用gcnew,这是您在托管堆上创建内容的方式,结果类型是托管句柄^. 这大致相当于用于new在非托管堆上创建对象,结果类型是一个指针,*

Declaring a local variable of type List<String^>(without the ^) is valid C++/CLI: It makes the local variable use stack semantics. There's no C# equivalent to that variable type, so most of the .Net library doesn't work completely with it: For example, there's no copy constructors to deal with assignment to variables without the ^. All of the managed APIs expect parameters with types that have the ^, so most times, you'll want to use that for your local variables.

声明类型为List<String^>(不带^)的局部变量是有效的 C++/CLI:它使局部变量使用堆栈语义。没有与该变量类型等效的 C#,因此大多数 .Net 库不能完全使用它:例如,没有复制构造函数来处理没有^. 所有托管 API 都希望参数的类型具有^,因此大多数情况下,您希望将其用于本地变量。

Important note: Everything in this answer applies to reference types in .Net (which are declared in C# as class, or in C++/CLI as ref classor ref struct). It does not apply to value types (C# struct, C++/CLI value classor value struct). Value types (such as int, float, DateTime, etc) are always declared & passed without the ^.

重要说明:此答案中的所有内容都适用于 .Net 中的引用类型(在 C# 中声明为class,或在 C++/CLI 中声明为ref classref struct)。它不适用于值类型(C# struct、C++/CLIvalue classvalue struct)。值类型(如intfloatDateTime,等)总是宣称与没有通过^