在 C# 中使用 C++ class 和字符串 (Dll)

Use C++ class in C# with strings (Dll)

我正在尝试在我的 C# 程序中使用我的 C++ class。所以我制作了一个 .dll 文件以在 C# 中使用它。我的问题是,我正在使用字符串。我的问题是:如何 return 一个 std::string 到我的 C# 程序?

我的 C++ class(头文件):

using namespace std;

class CComPort
{
public:     
    string ReadLine();          
    void WriteLine(string userInput);
};

我的dll代码:

string CppWrapper::CComPortWrapper::ReadLineWrapper()
{
    return comPort->ReadLine();
}

void CppWrapper::CComPortWrapper::WriteLineWrapper(string userInput)
{
    comPort->WriteLine(userInput);
}

我的 C# 代码:

comPort.WriteLineWrapper(tb_send.Text);

错误:

'CComPortWrapper.WriteLineWrapper(?,?)' is not supported by the language.

我尝试将 dll 文件更改为类似这样的文件,但没有成功:

void CppWrapper::CComPortWrapper::WriteLineWrapper(String ^ userInput)
{
    comPort->WriteLine(userInput);
}

正确的修改方法是什么?

看来您正在包装一个仅用于串行端口通信的 class。有一些方法可以直接从 C# 访问串口,而不需要 C++/CLI。除非 C++ class 中有很多逻辑不能 ported/would 难以移植到 C#,否则请考虑在 C# 中进行串行通信。


您还没有向我们展示您的 CComPortWrapper class 的声明。我假设它是 public ref class CComPortWrapper.

如果包装器的目标是使其可从托管语言(例如 C#)调用,那么您应该在声明中使用托管类型。

在这种情况下,您应该将CComPortWrapper的方法声明为采用&returnSystem::String^。在包装器中,将其转换为 to/from std::string,并以此调用非托管 class。

我建议使用 marshal_as 进行转换,特别是因为您要从一个 class 转换为另一个。您不需要处理显式分配内存或类似的事情;让每个字符串 class 管理自己的内存,让 marshal_as 处理复制和转换数据。

#include <msclr\marshal_cppstd.h>

using namespace System;

String^ CppWrapper::CComPortWrapper::ReadLineWrapper()
{
    std::string result = comPort->ReadLine();
    return marshal_as<String^>(result);
}

void CppWrapper::CComPortWrapper::WriteLineWrapper(String^ userInput)
{
    std::string input = marshal_as<std::string>(userInput);
    comPort->WriteLine(input);
}