C++/CLI 获取 "wrapper" class 对象以显示在 C# 中

C++/CLI getting "wrapper" class objects to show up in C#

我正在使用这个教程:https://www.red-gate.com/simple-talk/dotnet/net-development/creating-ccli-wrapper/

该教程在一个解决方案中使用了 3 个 Visual Studio 项目。 "Core" 项目是本机 C++ 端。 "Wrapper" 项目是 C++/CLI "bridge"。 "Sandbox" 项目是 C# 端。

现在我正在尝试修改它以使用我添加到核心的 C++ 函数,但我的新 Wrapper 方法和属性没有显示在 C# 中。我的最终目标是让 C# 应用程序将文本发送到 C++ 程序,然后 C++ 程序查询数据库,然后 return 匹配文本的前 20 条记录。现在,我只想向 C++ class 发送一个字符串和一个整数,并向 return 发送一个字符串向量,该字符串重复整数次。

我希望我能够在 Wrapper 中创建一个新的 属性,它会出现在 C# 中。我让 属性 指向 Core 中的一个函数,工作 properties/functions 和失败的函数之间唯一的显着区别是所使用的类型。在 Wrapper 项目头文件中,我添加了这样的函数:

void TypeAhead( std::string words, int count );

在 Wrapper .cpp 文件中,我添加了这个:

void Entity::TypeAhead( std::string words, int count )
{
    Console::WriteLine( "The Wrapper is trying to call TypeAhead()!" );
    m_Instance->TypeAhead( words, count );
}

我在Core项目中有配套的功能。在 Program.cs 中,实体 class 对象可以使用教程中的属性和函数,但不能使用我添加的那些。我需要更改什么才能从 Wrapper 项目中获取属性和函数以在 Sandbox 项目中使用?

我的仓库可以在这里找到:https://github.com/AdamJHowell/CLIExample

该函数签名与 C# 不兼容,因为它按值传递 C++ 本机类型。

您要找的签名是

void TypeAhead( System::String^ words, int count );

并且在调用核心函数之前您需要convert from the .NET String to a C++ std::string

问题是 std::string 在尝试公开给 .NET 时不是有效类型。它是纯 C++ 野兽。

变化:

void Entity::TypeAhead( std::string words, int count )
{
    Console::WriteLine( "The Wrapper is trying to call TypeAhead()!" );
    m_Instance->TypeAhead( words, count );
}

...至:

void Entity::TypeAhead( String^ words, int count )
{
    Console::WriteLine( "The Wrapper is trying to call TypeAhead()!" );

    // use your favourite technique to convert to std:string, this 
    // will be a lossy conversion.  Consider using std::wstring.
    std::string converted = // ...
    m_Instance->TypeAhead(converted, count );
}

在内部使用 std::wstring

正如 Tom 在下面的精彩评论中所指出的,您可能需要考虑使用 wstring,因为在从 .NET 字符串到 std::string 的转换中可能会出现保真度损失。要转换请参阅下面的 link。